From bd136d0c9d284b416c390577ffb6434f447360b5 Mon Sep 17 00:00:00 2001 From: venkato Date: Mon, 22 Oct 2018 06:49:04 +0100 Subject: [PATCH] create var from return value --- InvokationFramework.iml | 44 - ...oovyStaticCompilationVisitorFactory.groovy | 18 +- .../langi/JrrStaticCompilationVisitor.java | 13 +- resources/icon/idea/reload_class.png | Bin 0 -> 519 bytes resources/tcpmon/Quickfixj_sample.groovy | 67 + resources/tcpmon/Sam.groovy | 1 - resources/tcpmon/extMethodTester.groovy | 23 + resources/tcpmon/rstatester.groovy | 4 + richNpe/antimodule64.dll | Bin 0 -> 408266 bytes richNpe/richNPE64.dll | Bin 0 -> 421206 bytes richNpe/richNPE64.so | Bin 0 -> 12656 bytes .../nonjdk/archiver/JrrCommonsArchiver.groovy | 149 ++ .../CommonsArchiverOriginal.groovy | 92 ++ .../javassist/ClassRedefintions.groovy | 90 -- .../javassist/JrrJavassistUtils.groovy | 58 +- .../utilities/nonjdk/BaseDirSetting.groovy | 30 + .../utilities/nonjdk/ConsoleRedirect.groovy | 21 +- .../nonjdk/ConsoleTextFunctionPrefix.groovy | 17 + .../utilities/nonjdk/FileEnumContains.groovy | 13 + .../utilities/nonjdk/FileRotate.groovy | 63 +- .../utilities/nonjdk/FileUtilsJrr.groovy | 644 ++++++++ .../utilities/nonjdk/GeneralUtils.groovy | 139 +- .../nonjdk/LastByteArrayOutputStream.groovy | 13 +- .../utilities/nonjdk/NpeFixAgent.groovy | 42 + .../utilities/nonjdk/RedirectOutStream.groovy | 3 + .../utilities/nonjdk/StringFindRange.groovy | 34 +- .../utilities/nonjdk/ThreeResult.groovy | 6 + .../utilities/nonjdk/TwoResult.groovy | 5 + .../nonjdk/asmow2/AsmConsoleDecompiler.groovy | 60 + .../asmow2/AsmConsoleDecompilerVisitor.groovy | 38 + .../utilities/nonjdk/asmow2/AsmUtils.groovy | 132 ++ .../nonjdk/asmow2/ClassRemapperConst.groovy | 38 + .../nonjdk/asmow2/EmptyClassVisitor.groovy | 25 + .../asmow2/EmptyMethodClassVisitor.groovy | 48 + .../nonjdk/asmow2/EmptyMethodVisitor.groovy | 29 + .../nonjdk/asmow2/MethodRemapperConst.groovy | 56 + .../nonjdk/asmow2/SimpleRemapperUsed.groovy | 27 + .../accessmodif/AccessClassVisitor.groovy | 192 +++ .../accessmodif/AccessModifController.groovy | 163 ++ .../DirAccessModifController.groovy | 41 + .../JarAccessModifController.groovy | 56 + .../accessmodif/JrrMethodVisitor.groovy | 30 + .../accessmodif/ZipEntryCallbackAm.groovy | 46 + .../asmow2/usedclasses/UsedClasses.groovy | 107 ++ .../verifier/AsmByteCodeVerifier.groovy | 69 + .../verifier/DirByteCodeVerifier.groovy | 53 + .../verifier/JarByteCodeVerifier.groovy | 43 + .../asmow2/verifier/JrrAsmVerifier.groovy | 43 + .../nonjdk/classpath/AndroidArchive.groovy | 23 + .../nonjdk/classpath/CheckNonCache2.groovy | 6 +- .../classpath/DefaultClasspathAdder.groovy | 18 +- .../classpath/GeneralBiblioRepository.groovy | 56 + .../classpath/IvyDepResolverSetter.groovy | 4 +- .../classpath/MavenRepositoriesEnum.groovy | 14 +- .../nonjdk/classpath/SshConsoleAdder.groovy | 8 +- .../classpath/UrlCLassLoaderUtils2.groovy | 22 +- .../nonjdk/classpath/UserBintrayRepo.groovy | 54 + .../ClassPathCalculatorEnumConverter.groovy | 37 + .../ClassPathCalculatorGroovyWise.groovy | 6 +- ...athCalculatorGroovyWithDownloadWise.groovy | 22 +- .../ClassPathCalculatorSup2Groovy.groovy | 69 +- .../helpers/AddFileWithSources.groovy | 129 +- .../helpers/AddFileWithSourcesDummy.groovy | 29 + .../classpath/helpers/AddToAdderSelf.groovy | 12 + .../helpers/BinaryWithSource3.groovy | 29 + .../classpath/helpers/ClassPathInit3.groovy | 9 +- .../classpath/helpers/FileToFileRef.groovy | 7 +- .../helpers/MavenRetryDownloader.groovy | 11 + .../nonjdk/classpath/helpers/UnzipRef.groovy | 30 + .../nonjdk/classpath/helpers/UrlRef.groovy | 35 + .../helpers/ZeroOverheadFileRef.groovy | 12 + .../inittracker/InitLogTracker.groovy | 86 ++ .../inittracker/InitLogTrackerMBean.groovy | 19 + .../classpath/inittracker/LogItem.groovy | 22 + .../classpath/refs/AllMavenIdsRefs.groovy | 74 + .../nonjdk/classpath/refs/AntMavenIds.groovy | 8 +- .../nonjdk/classpath/refs/AsmOw.groovy | 39 + .../refs/BouncyCastleMavenIds.groovy | 23 +- .../classpath/refs/ComplexGitRefs.groovy | 2 +- .../classpath/refs/CustObjMavenIds.groovy | 30 +- .../classpath/refs/CustomRefsUrls.groovy | 37 + .../classpath/refs/DerbyMavenIds.groovy | 7 +- .../nonjdk/classpath/refs/GitMavenIds.groovy | 50 + .../classpath/refs/GitReferences.groovy | 72 +- .../nonjdk/classpath/refs/GitSomeRefs.groovy | 96 ++ .../classpath/refs/GitlabLibsMavenIds.groovy | 86 ++ .../classpath/refs/Gradle5MavenIds.groovy | 141 ++ .../classpath/refs/GroovyMavenIds.groovy | 31 +- .../classpath/refs/JeditermBinRefs.groovy | 14 +- .../classpath/refs/JeditermBinRefs2.groovy | 11 +- .../classpath/refs/JrrStarterJarRefs.groovy | 12 +- .../classpath/refs/JrrStarterJarRefs2.groovy | 34 + .../classpath/refs/JrrStarterProjects.groovy | 32 +- .../classpath/refs/KafkaMavenIds.groovy | 56 + .../classpath/refs/KotlinMavenIds.groovy | 103 ++ .../classpath/refs/LatestMavenIds.groovy | 172 ++- .../classpath/refs/Log4j2MavenIds.groovy | 15 +- .../refs/MaryDependentMavenIds.groovy | 24 + .../classpath/refs/MaryTtsMavenIds.groovy | 40 + .../refs/MavenIdAndRepoCustom.groovy | 36 + .../classpath/refs/MavenMavenIdRandom.groovy | 40 + .../classpath/refs/MavenMavenIds.groovy | 49 + .../refs/MavenResolverMavenIds.groovy | 45 + .../classpath/refs/MigLayoutMavenIds.groovy | 16 +- .../classpath/refs/NettyMavenIds.groovy | 68 + .../classpath/refs/NexusSearchMavenIds.groovy | 18 +- .../classpath/refs/Okhttp3MavenIds.groovy | 41 + .../nonjdk/classpath/refs/Pi4j.groovy | 36 + .../classpath/refs/ProguardMavenIds.groovy | 17 +- .../classpath/refs/SquirrelSqlMavenIds.groovy | 15 +- .../nonjdk/classpath/refs/SshdMavenIds.groovy | 21 +- .../nonjdk/classpath/refs/SvnRefs.groovy | 1 - .../refs/TwelvemonkeysImageioMavenIds.groovy | 56 + .../repohash/GrapeRepoHashToFileMap.groovy | 9 +- .../repohash/MavenRepoHashToFileMap.groovy | 3 + .../classpath/search/BintraySearch.groovy | 73 + .../search/BintraySearchResult.groovy | 23 + .../search/FindMavenIdsAndDownload.groovy | 20 +- .../classpath/search/MavenElementsGet.groovy | 122 ++ .../search/MavenResponseParser.groovy | 62 +- .../classpath/search/MavenSearch.groovy | 59 +- .../enumutils/EnumCustomNameResolver.groovy | 56 + .../nonjdk/enumutils/EnumNameProvider.groovy | 13 + .../utilities/nonjdk/git/CloneGitRepo2.groovy | 113 -- .../utilities/nonjdk/git/CloneGitRepo4.groovy | 66 +- .../utilities/nonjdk/git/CommitApplier.groovy | 225 +++ .../git/CommitIdCanonicalTreeParser.groovy | 21 + .../utilities/nonjdk/git/DiffApplier.groovy | 410 +++++ .../nonjdk/git/DiffApplierFactory.groovy | 20 + .../nonjdk/git/DiffEntryUtils.groovy | 56 + .../nonjdk/git/DiffFormatterJrr.groovy | 53 + .../utilities/nonjdk/git/DiffWriter.groovy | 99 ++ .../nonjdk/git/GitBinaryAndSourceRef.groovy | 13 +- .../nonjdk/git/GitProgressMonitorJrr.groovy | 105 ++ .../utilities/nonjdk/git/GitRef.groovy | 13 +- .../utilities/nonjdk/git/GitRefRef.groovy | 4 +- .../utilities/nonjdk/git/GitRemoteFind.groovy | 44 + .../nonjdk/git/GitRepoCheckoutFork.groovy | 137 ++ .../utilities/nonjdk/git/GitRepoUtils.groovy | 605 ++++++++ .../utilities/nonjdk/git/GitSpec.groovy | 29 +- .../utilities/nonjdk/git/GitSpecRef.groovy | 16 + .../nonjdk/git/GitToSvnConverter.groovy | 56 + .../nonjdk/git/JrrGitSshFactory.groovy | 51 - .../nonjdk/git/RemoteSessionGitJrr.groovy | 19 + .../utilities/nonjdk/git/SvnRef.groovy | 8 +- .../utilities/nonjdk/git/SvnSpec.groovy | 29 +- .../utilities/nonjdk/git/SvnSpecRef.groovy | 19 + .../EclipseJavaCompilerPure.groovy | 32 +- .../nonjdk/langutils/JavaStartTime.groovy | 23 + .../nonjdk/langutils/LangUtils.groovy | 70 + .../NativeLibraryLoaderChecker.groovy | 32 + .../langutils/ObjectStringComparator.groovy | 41 + .../FilterOutputStreamJrr.groovy | 58 + .../nativeprocess/NativeProcessResult.groovy | 205 +++ .../nativeprocess/NonClosableStream.groovy | 21 + .../nonjdk/sfdownloader/Servers.groovy | 4 + .../nonjdk/sfdownloader/SfLink.groovy | 10 +- .../sfdownloader/SourceForgeDownloader.groovy | 6 +- .../nonjdk/sfdownloader/UrlProvided.groovy | 4 +- .../utilities/nonjdk/store/JavaBean.groovy | 5 + .../utilities/nonjdk/store/JavaBean2.groovy | 5 +- .../nonjdk/store/JavaBeanStore.groovy | 25 +- .../utilities/nonjdk/store/ListStore.groovy | 13 +- .../utilities/nonjdk/store/MapStore.groovy | 5 +- .../nonjdk/store/ObjectWriter.groovy | 107 +- .../utilities/nonjdk/store/Writer3.groovy | 61 +- .../utilities/nonjdk/store/Writer3Sub.groovy | 4 +- .../utilities/nonjdk/store/Writer4Sub.groovy | 3 - .../nonjdk/store/Writer5Class.groovy | 3 +- .../utilities/nonjdk/store/Writer6Sub.groovy | 12 +- .../utilities/nonjdk/store/Writer7Sub.groovy | 28 + .../nonjdk/swing/JrrSwingUtils.groovy | 22 +- .../nonjdk/swing/QrCodeCreator.groovy | 95 ++ .../compiler3/JavacJavaCompilerC.groovy | 2 +- .../javac/JavacCompilerFactoryC.groovy | 9 +- .../javac/JavacJavaCompiler2C.groovy | 14 +- .../EclipseClassPathChecker.java | 68 + .../customrunners/CustomRunnersView.java | 194 +++ .../nonjdk/eclipse/init/AddIgnoreClasses.java | 27 + .../misc}/MyIDEWorkbenchErrorHandler.java | 64 +- .../eclipse/misc/SetEclipseLogHandler.java | 55 + .../proxy/NoProxyEclipseProxyData.java | 45 + .../UserLibraryConfigurator.java | 62 + .../eclipse/workingset/WorkingSetUpdate.java | 41 + .../forcepush/MyEclipseClassLoaderHook.java | 7 +- .../git/forcepush/SetEclipseLogHandler.java | 38 - .../nik/git/forcepush/jrr/PushForceImpl2.java | 27 + .../eclipse/EclipseLunaClasspathAdd.groovy | 44 +- .../eclipse/JrrEclipseStartupSettings.java | 6 + .../utilities/nonjdk/eclipse/MyStartup.java | 1 - .../eclipse/svn/SvnAdapterManagerJrr.java | 53 + .../nonjdk/eclipse/svn/SvnUpdater2.java | 0 .../eclipse/svn/password/ActivatorJrr.java | 59 + .../eclipse/svn/password/SvnClientJrr.java | 79 + .../svn/password/SvnKitClientAdapterJrr.java | 83 + .../nonjdk/IfFrameworkResourceDirs.groovy | 8 +- .../nonjdk/IfFrameworkSrcDirs.groovy | 45 +- .../InfocationFrameworkAndGitAdder.groovy | 30 +- .../InfocationFrameworkStructure.groovy | 1 + .../nonjdk/JavaVersionChecker.groovy | 31 + .../classpath/helpers/ChildFileLazy.groovy | 15 + .../classpath/helpers/FileChildLazyRef.groovy | 44 + .../nonjdk/git/hub/GitHubUtils.groovy | 60 + .../nonjdk/git/lab/GitLabUtils.groovy | 104 ++ .../nonjdk/git/lab/GitlabMrMonitor.groovy | 171 +++ .../git/lab/GitlabPipelineRunner.groovy | 202 +++ .../compiler3/AddGroovyToParentCl.groovy | 3 +- .../nonjdk/compiler3/AddToClassloader.groovy | 11 + .../compiler3/CompileGroovyExtMethod.groovy | 3 +- .../compiler3/CompileRequestClient.groovy | 98 +- .../compiler3/CompileRequestRemote.groovy | 16 +- .../compiler3/CreateGroovyClassLoader.groovy | 32 +- .../nonjdk/compiler3/GroovyCompiler.groovy | 39 +- .../compiler3/GroovyCompilerParams.groovy | 42 +- .../nonjdk/compiler3/SetCallerClass.groovy | 80 + .../compiler3/eclipse/EclipseCompiler3.groovy | 27 +- .../eclipse/EclipseCompilerFactoryC.groovy | 10 +- .../eclipse/EclipseJavaCompiler2C.groovy | 55 +- .../nonjdk/audio/JrrText2Speech.groovy | 67 + .../idea/IdeaClasspathImportFailed.groovy | 41 + .../idea/IdeaClasspathImportedFine.groovy | 24 + .../idea/github/IdeaGitgubAddRepo.groovy | 39 + .../idea/laumcherbuild/IdeaBRunnerImpl.java | 27 +- .../IdeaBuildRunnerSettings.java | 46 + .../IdeaBuilderAddGroovyRuntime.java | 129 +- .../idea/laumcherbuild/LauncherImpl.java | 16 +- .../org/jetbrains/jps/cmdline/Launcher.java | 4 - .../jps/cmdline/LauncherOriginal.java | 63 + .../compile/IdeaRunnerBuilderCompiler.groovy | 50 +- .../idea/laumcherbuild2/AddMavenIds.groovy | 3 +- .../idea/laumcherbuild2/IdeaBRunner21.groovy | 2 +- .../idea/laumcherbuild2/IdeaBRunner33.groovy | 352 ++++- .../idea/laumcherbuild2/IdeaBRunner34.groovy | 30 +- .../idea/laumcherbuild2/Redirector.groovy | 7 +- .../jrr/IndexReadyListener.groovy | 80 +- .../filecompletion/jrr/InitPlugin.groovy | 5 +- .../filecompletion/jrr/InitPlugin2.groovy | 18 +- .../jrr/a/MyCompletionContributorImpl.groovy | 3 +- .../a/actions/CompletionProviderCommon.java | 14 + .../a/actions/ReloadClassActionImpl.groovy | 27 +- .../jrr/a/actions/RemoteRunActionImpl.groovy | 4 +- .../actions/openfile/IdeaOpenFileUtils.groovy | 9 +- .../JmxLocalhostConnections.groovy | 12 + .../ReloadClassConnectionPanel.groovy | 146 ++ .../reloadclass/ReloadClassSettingsI.groovy | 16 + .../CharsetCompletionProviderImpl.groovy | 16 +- .../a/file/FileCompletionProviderImpl.groovy | 6 +- .../a/file/MyAcceptFileProviderImpl.groovy | 1346 ++++++++++------- .../jrr/a/file/SpecialMethodName.groovy | 15 + .../jrr/a/file/sample/SampleEnum.groovy | 22 + .../jrr/a/file/sample/SampleGroovy.groovy | 62 +- .../jrr/a/file/sample/SampleJava.java | 39 +- .../SimpleDateFormatHelper.groovy | 12 +- .../JavassistCompletionProviderImpl.groovy | 6 +- .../a/jrrlib/JrrCompletionProviderImpl.groovy | 6 +- .../maven/MavenCompletionProviderImpl.groovy | 6 +- .../a/maven/MyAcceptMavenProviderImpl.groovy | 11 +- .../SystemPropCompletionProviderImpl.groovy | 6 +- .../timezone/TZCompletionProviderImpl.groovy | 6 +- .../FieldResolvedDirectly.groovy | 87 ++ .../FieldResolvedDirectlyMoreComplex.groovy | 112 ++ .../FileChooserListener.java | 2 + .../IdeaAddFileWithSources.groovy | 25 +- .../IdeaAddFileWithSourcesFactory.groovy | 18 + .../IdeaLibManagerSwing.groovy | 32 +- .../IdeaRuntimeClassRefrences.groovy | 42 + .../LibConfigurator8.groovy | 7 +- .../jrr/librayconfigurator/LibItem.groovy | 3 +- .../jrr/librayconfigurator/LibManager3.groovy | 86 +- .../ideasdk/IdeaRuntimeClasspath.groovy | 225 +++ .../ideasdk/IdeaSdkAddSourcesUtils.groovy | 34 +- .../ideasdk/IdeaSdkToLibAdapterRead.groovy | 10 + .../filecompletion/share/IdeaReBuilder.groovy | 132 ++ .../IdeaJavaRunner2Settings.groovy | 10 + .../share/OSIntegrationIdea.groovy | 53 +- .../AddJrrLibToCommonIdeaClassloader2.groovy | 17 +- .../idea/CurrentIdeaVersionUtils.groovy | 26 + .../nonjdk/idea/CustomRunners.groovy | 12 +- .../nonjdk/idea/IdeaMavenRepoParser.groovy | 95 ++ .../idea/IdeaRedefineClassloader.groovy | 100 +- .../IdeaRedefineClassloaderSupport.groovy | 2 - .../idea/IdeaRedefineClassloaderTester.groovy | 1 + .../nonjdk/idea/RedefineIdeaClassUtils.groovy | 4 +- .../nonjdk/idea/ReloadClassIdeaToolbar.groovy | 67 + .../IdeaClassPathRuntimeTester.groovy | 74 + .../AddFilesToClassLoaderGroovyIdea.groovy | 17 + .../idea/init/IdeaClassLoadWarmup.groovy | 40 + .../idea/init/IdeaClassPathSettings.groovy | 9 +- .../nonjdk/idea/init/IdeaClasspathAdd.groovy | 86 +- .../nonjdk/idea/init2/IdeaInit5.groovy | 3 + .../nonjdk/idea/jrr/JrrIdeaBeanCommon.groovy | 5 +- .../nonjdk/idea/set2/SettingsRef.groovy | 12 +- .../classpathhook/JavaClassPathHook.groovy | 13 +- .../classpathhook/JavaClassPathHookV2.groovy | 230 +++ .../classpathhook/JavaStartConfigHook.groovy | 16 +- .../nonjdk/idea/IdeaClassPathTester.groovy | 23 +- .../nonjdk/idea/IdeaCommonInit.groovy | 20 +- .../nonjdk/idea/IdeaProxyDisable.groovy | 23 + .../nonjdk/idea/init2/IdeaInit4.groovy | 10 +- .../nonjdk/idea/init2/IdeaInit6.groovy | 7 +- .../JrrIdwPropertyMapManager.groovy | 83 + .../nonjdk/idwutils/FrameLocationInfo.groovy | 9 +- .../nonjdk/idwutils/IdwActions.groovy | 6 +- .../nonjdk/idwutils/IdwFrameCreator.groovy | 66 + .../utilities/nonjdk/idwutils/IdwUtils.groovy | 3 + .../nonjdk/idwutils/IdwUtils2.groovy | 9 +- .../nonjdk/idwutils/IdwUtilsStarter.groovy | 7 + .../nonjdk/idwutils/IdwWindowFinder.groovy | 3 +- ...va => MyDockingWindowTitleProvider.groovy} | 4 +- .../nonjdk/idwutils/QrCoderPaneCreator.groovy | 54 + .../{Shortcuts.java => Shortcuts.groovy} | 6 +- .../nonjdk/idwutils/TextAreaAndView.groovy | 14 +- .../idwutils/alerttable/AlertTable.groovy | 128 ++ .../alerttable/AlertTableColumns.groovy | 13 + .../alerttable/AlertTableWrapper.groovy | 53 + .../nonjdk/swing/SimpleFrameCreator.groovy | 12 +- .../nonjdk/classpath/java8/VmUtilities.groovy | 22 + .../nonjdk/log/java8}/JdkCoreMethods.groovy | 6 +- .../jcraft/jsch/ChannelExecOriginal.groovy | 110 ++ .../jsch/ChannelForwardedTCPIPOriginal.groovy | 15 + .../jcraft/jsch/ChannelSessionOriginal.groovy | 13 + .../jcraft/jsch/ChannelSftpOriginal.groovy | 105 ++ .../jcraft/jsch/ChannelShellOriginal.groovy | 103 ++ .../com/jcraft/jsch/ChannelX11Original.groovy | 13 + .../jcraft/jsch/HostCheckResultEnum.groovy | 21 + .../jcraft/jsch/JrrJschSessionOriginal.groovy | 60 + .../com/jcraft/jsch/JrrJschStaticUtils.java | 18 + .../jcraft/jsch/JrrKnowHostOriginal.groovy | 40 + .../com/jcraft/jsch/JrrSchSessionLog.groovy | 21 + .../com/jcraft/jsch/JschIOOriginal.groovy | 70 + src-jsshext/com/jcraft/jsch/SshCmds.groovy | 28 + .../jsch/UserAuthGSSAPIWithMICOriginal.groovy | 16 + ...UserAuthKeyboardInteractiveOriginal.groovy | 16 + .../jsch/UserAuthLoggingInterface.groovy | 21 + .../jcraft/jsch/UserAuthNoneOriginal.groovy | 16 + .../jcraft/jsch/UserAuthNoneWithLogging.java | 164 ++ .../jsch/UserAuthPasswordOriginal.groovy | 16 + .../jsch/UserAuthPasswordWithLogging.java | 229 +++ .../jsch/UserAuthPublicKeyOriginal.groovy | 15 + .../jsch/UserAuthPublicKeyWithLogging.java | 269 ++++ .../nonjdk/log/JdkLoggerExtentionClass.java | 47 +- .../BasicCredentialsProviderMavenJrr.groovy | 49 + .../http/JrrMavenDownloadHttpHandler.java | 55 + .../maven/http/JrrMavenHttpUtils.groovy | 96 ++ .../http/NTLMSchemeFactoryMavenJrr.groovy | 47 + .../maven/http/NTLMSchemeMavenJrr.groovy | 63 + ...ProxyAuthenticationStrategyMavenJrr.groovy | 92 ++ .../nonjdk/maven/launcher/JrrMavenCli.java | 30 + .../maven/launcher/JrrMavenCliWrapper.java | 194 +++ .../utils/JrrClassWorldListener.groovy | 23 + .../maven/launcher/utils/RealmDumper.groovy | 32 + .../apache/maven/cli/CliRequestPublic.java | 60 + .../maven/pluginext/JrrMavenPluginExt.java | 37 + .../pluginext/NoopMavenModelValidator.java | 19 + .../utilities/nonjdk/maven/MavenRunner.groovy | 124 ++ .../nonjdk/maven/MavenRunnerLauncher.groovy | 37 + .../MavenHttpTransporterFactoryJrr.groovy | 33 + .../maven/mavenupload/MavenUploader.groovy | 139 ++ .../mavenupload/MavenUploaderMavenId.groovy | 37 + .../internal/MavenSettingsJrr.groovy | 11 + .../RemoteSnapshotMetadataGeneratorJrr.java | 110 ++ .../internal/RemoteSnapshotMetadataJrr.java | 174 +++ .../SnapshotMetadataGeneratorFactoryJrr.java | 55 + .../transport/http/HttpTransporterJrr.java | 604 ++++++++ .../netbeans/heapwalker/OpenInIdeHeap.groovy | 142 ++ .../GroovyShellGuiRSyntaxTextArea.groovy | 598 ++++---- .../rstacore/LogImprovedJarManager.groovy | 28 + .../OpenInBrowserLinkGeneratorResult.groovy | 26 + .../RSyntaxTextAreaCodeAssistUndoFix.groovy | 81 + ...yntaxTextAreaCodeAssistWithCustMenu.groovy | 46 +- .../rstacore/RstaLangSupportStatic.groovy | 33 +- .../nonjdk/rstacore/RstaOpenMember.groovy | 106 +- .../TextAssociatedLinkGenerator.groovy | 74 + .../nonjdk/rstarunner/RstaRunner.groovy | 147 +- .../RstaRunnerWithStackTrace.groovy | 19 +- .../RstaRunnerWithStackTrace2.groovy | 148 +- .../RstaRunnerWithStackTrace3.groovy | 155 ++ .../rstarunner/StopRequestIndicator.groovy | 13 + .../timmoson/client/ClientParams.java | 5 +- .../timmoson/client/ClientSendRequest.java | 7 +- .../timmoson/client/ClientStaticUtils.java | 3 +- .../timmoson/client/DGCMonitor.java | 5 +- .../timmoson/client/ProxyCall.java | 0 .../client/ProxyCallDiffClassloader.java | 0 .../timmoson/client/ProxyCallInvocation.java | 4 +- .../timmoson/client/RequestInfoCleint.java | 5 +- .../client/TcpSessionClosedListener.java | 0 .../timmoson/client/TimmosonSessionStore.java | 0 .../TimmosonSessionStoreAndBuilder.java | 7 +- .../client/TimmosonSessionStoreSimple.java | 0 .../TelnetTimmosonSessionStoreSimple.java | 0 .../timmoson/common/CallBackSession.java | 5 +- .../timmoson/common/CallInfoServer.java | 0 .../timmoson/common/ClientInfo.java | 5 +- .../timmoson/common/TcpCallCommon.java | 4 - .../common/debug/LocalSessionNotifier.java | 0 .../common/debug/LocalSessionRequestBean.java | 5 +- .../common/debug/TcpSessionNotifier.java | 0 .../common/debug/TcpSessionTrackerBean.java | 5 +- .../timmoson/common/remoterun/IfRegister.java | 5 +- .../remoterun/InvokactionRemoreRun.java | 2 +- .../timmoson/common/sertcp/Consts.java | 0 .../common/sertcp/IfSharedObjects.java | 3 - .../sertcp/MakeProxyDiffClassLoader.java | 3 +- .../ProxyCallInvocationDiffClassloader.java | 3 +- .../timmoson/common/sertcp/RemoteService.java | 20 +- .../timmoson/common/sertcp/TcpSession.java | 19 +- .../common/sertcp/TimmosonSettings.groovy | 16 + .../common/telnet/TelnetRemoteService.java | 10 +- .../timmoson/common/telnet/TelnetSession.java | 5 +- .../transferedobjects/JmxServiceId.java | 0 .../transferedobjects/RemoteObjectClient.java | 3 - .../transferedobjects/RemoteObjectServer.java | 3 - .../common/transferedobjects/ReponseBean.java | 3 - .../common/transferedobjects/RequestBean.java | 4 +- .../common/transferedobjects/ServiceId.java | 0 .../transferedobjects/SessionServiceId.java | 0 .../transferedobjects/StaticServiceId.java | 0 .../localcall/CallInfoServerCallBack.java | 3 - .../timmoson/localcall/LocalCallUtils.java | 4 +- .../timmoson/localcall/LocalSession.java | 3 - .../timmoson/server/GetReponseHandler.java | 0 .../timmoson/server/ServerUtilsStatic.java | 4 +- .../server/ServiceCallServerInvoker.java | 5 +- .../server/ServiceCallServerInvokerDebug.java | 5 +- .../ServiceCallServerInvokerDebugFile.java | 7 +- .../timmoson/server/ServiceInfo.java | 3 - .../timmoson/server/ServiceLocator.groovy | 9 +- .../timmoson/server/ServiceSupport.groovy | 0 .../timmoson/server/TcpCallInfoServer.java | 3 - .../timmoson/server/TcpServiceObject.java | 3 - .../timmoson/server/TcpSocketLlistener.java | 4 +- .../server/service/DefaultService.java | 0 .../timmoson/server/service/TcpService.java | 5 +- .../timmoson/server/service/TestService.java | 0 .../server/telnet/TelnetRequestBean.java | 5 +- .../telnet/TelnetServerUtilsStatic.java | 3 +- .../server/telnet/TelnetSocketLlistener.java | 0 .../timmoson/testservice/CallbackService.java | 4 +- .../timmoson/testservice/SampleService.java | 5 +- .../utilities/nonjdk/AppRunner.groovy | 9 +- .../utilities/nonjdk/InitGeneral.groovy | 98 +- .../utilities/nonjdk/JavaProcessRunner.groovy | 98 +- .../utilities/nonjdk/LogExitTimeHook.groovy | 4 +- .../utilities/nonjdk/MainMethodRunner.groovy | 3 +- .../utilities/nonjdk/NetworkCheck.groovy | 37 +- .../utilities/nonjdk/ProxyAuth.groovy | 1 + .../utilities/nonjdk/ProxySetter.groovy | 5 + .../SimpleUncaughtExceptionHandler.groovy | 13 +- .../utilities/nonjdk/VersionComparator.groovy | 122 ++ .../nonjdk/antutils/JrrAntUtils.groovy | 2 +- .../nonjdk/antutils/JrrAntUtils2.groovy | 53 + .../nonjdk/antutils/ZipElement.groovy | 21 + .../nonjdk/antutils/ZipElement2.groovy | 20 + .../nonjdk/antutils/ZipElements.groovy | 97 ++ .../nonjdk/apprunner/ProgramInfo.java | 3 + .../nonjdk/apprunner/ProgramRunner.groovy | 29 +- .../apprunner/RunProgramOnStart2.groovy | 61 +- .../apprunner/RunProgramOnStart3.groovy | 64 + .../nonjdk/awtdebug/EventQueueDebug.groovy | 11 +- .../nonjdk/cacheddata/CachedData.groovy | 24 + .../classpath/AddDirectoryWithFiles.groovy | 53 + .../classpath/CustomObjectHandlerImpl.groovy | 313 +++- .../CustomObjectHandlerSetter.groovy | 2 + .../CustomObjectHandlerSetter2.groovy | 6 +- .../nonjdk/classpath/MavenDepParser.groovy | 73 +- .../nonjdk/classpath/MavenDepParser2.groovy | 2 +- .../calchelpers/BintrayJarDownloader.groovy | 66 + .../classloader/AddedLocationDetector.groovy | 53 + .../classloader/AllClasspathAnalysis.groovy | 203 +++ .../classloader/DumpLoadedClasses.groovy | 85 ++ .../DuplicateClassesDetector.groovy | 130 ++ .../classloader/GetClassesFromLocation.groovy | 69 + .../classloader/UsedByAnalysis.groovy | 227 +++ ...dFilesToClassLoaderGroovyDownloader.groovy | 5 +- .../console/JrrConfigGenerator.groovy | 4 +- .../console/JrrConsoleDecompiler.groovy | 23 +- .../classpath/console/JrrIdeaGenerator.groovy | 10 +- .../classpath/console/JrrJarRunner.groovy | 80 + .../classpath/console/JrrSvnConsole.groovy | 15 + .../console/auxp/ConsoleCompiler.groovy | 21 +- .../auxp/CopyResourcesFromDirToDir.groovy | 3 +- .../classpath/helpers/SrcDirFinder.groovy | 57 + .../classpath/refs2/EclipseLatest.groovy | 25 + .../tester/ClassPathTesterHelper.groovy | 130 +- .../tester/ClassPathTesterHelper2.groovy | 313 ++++ .../classpath/tester/ClasspathTester.groovy | 9 +- .../tester/JavaToolsJarTester.groovy | 30 + .../classpath/tester/ProblemInfoClass.groovy | 15 + .../tester/StdClassPathTester.groovy | 39 +- .../classuggest/GetListOfClasses.groovy | 92 ++ .../compile/AutoCompleteCompiler.groovy | 12 +- .../compile/CompileGroovyExtMethod2.groovy | 3 +- .../compile/DockingFramesCompiler.groovy | 3 +- .../compile/EclipsePluginsCompiler.groovy | 5 +- .../nonjdk/compile/GenericCompiler.groovy | 9 +- .../compile/GroovyCustomCompiler.groovy | 19 +- .../compile/IdeaInitPluginCompiler.groovy | 21 +- .../nonjdk/compile/IdeaPluginCompiler.groovy | 15 +- .../nonjdk/compile/IdeaSourcesCompiler.groovy | 5 +- .../nonjdk/compile/IfFrameworkCompiler.groovy | 109 +- .../compile/JeditTermClassChecker.groovy | 15 + .../JeditTermCompilerConsoleCompiler.groovy | 121 +- .../nonjdk/compile/JhexCompiler.groovy | 19 +- .../nonjdk/compile/JnaCoreCompiler.groovy | 3 +- .../nonjdk/compile/JnaJvmtiCompiler.groovy | 8 +- .../nonjdk/compile/JrrCoreCompiler.groovy | 27 +- .../compile/JrrJavassistUtilsCompiler.groovy | 43 +- .../nonjdk/compile/JrrUtilsCompiler.groovy | 10 +- .../nonjdk/compile/RDesktopCompiler.groovy | 3 +- .../nonjdk/compile/RstaCoreCompiler.groovy | 5 +- .../nonjdk/compile/RstaMainCompiler.groovy | 3 +- .../nonjdk/compile/SshConsoleCompiler.groovy | 7 +- .../compile/TrolCommanderCompiler.groovy | 3 +- .../compile/TrolCommanderCompilerAux.groovy | 2 +- .../auxh/AddGroovyToParentClResolver.groovy | 28 + .../consoleprograms/ConsoleProgramEnum.groovy | 38 + .../consoleprograms/ConsolePrograms.groovy | 15 +- .../DefaultConsolePrograms.groovy | 33 +- .../consoleprograms/GitCheckoutConsole.groovy | 21 +- .../GradleWrapperRunner.groovy | 43 + .../nonjdk/crypto/AsymetricKeyBC2.groovy | 67 + .../nonjdk/crypto/AsymetricKeyChecker2.groovy | 120 ++ .../nonjdk/crypto/AsymetricKeyLoader3.groovy | 118 ++ .../crypto/AsymetricKeyLoaderAny.groovy | 122 ++ .../crypto/AsymetricKeyLoaderJsch.groovy | 31 + .../crypto/AsymetricKeyLoaderSshtools.groovy | 67 + .../nonjdk/crypto/CertificateChecker.groovy | 158 ++ .../utilities/nonjdk/crypto/CipherMode.groovy | 24 + .../nonjdk/crypto/EcPrivateKeyChecker.groovy | 106 ++ .../utilities/nonjdk/crypto/EncDec.groovy | 70 + .../utilities/nonjdk/crypto/EncInfo.groovy | 46 + .../crypto/JavaSecurityProviders.groovy | 27 + .../utilities/nonjdk/crypto/KeyType.groovy | 14 + .../nonjdk/cvsutils/CsvComparator.groovy | 27 +- .../nonjdk/cvsutils/CsvNormalizer.groovy | 71 + .../decompiler/DecompilerAddFiles.groovy | 18 +- .../depanalise/AddFilesToJavasistPool.groovy | 2 +- .../depanalise/DependencyChecker.groovy | 3 + .../disktest/DiskPerformanceTester.groovy | 194 +++ .../DiskPerformanceTesterWrapper.groovy | 87 ++ .../downloadutils/LessDownloader.groovy | 16 +- .../downloadutils/UrlDownloadUtils3.groovy | 30 +- .../downloadutils/WinptyDownloader.groovy | 10 +- .../fileloayout/GitWinFilesLayout.groovy | 40 + .../nonjdk/generalutils/LogCounter.groovy | 92 ++ .../utilities/nonjdk/gi2/GitPushHook.groovy | 20 +- .../nonjdk/gi2/GitRepoUpdater.groovy | 56 +- .../nonjdk/git/JrrGitSshFactory.groovy | 95 ++ .../groovy/ExtentionMethodChecker.groovy | 36 + .../groovy/ExtentionMethodChecker2.groovy | 24 + .../nonjdk/ivy/IvyDepResolver3.groovy | 34 + .../ivy/IvyDownloadFromSpecifiedSource.groovy | 24 + .../ivy/JrrDependecyAmenderDefault.groovy | 58 + .../nonjdk/ivy/JrrIvyURLHandler.groovy | 96 ++ .../nonjdk/ivy/ManyReposDownloaderImpl.groovy | 121 ++ .../ivy/MavenManyReposDownloader.groovy | 71 + .../nonjdk/ivy/OnRepoCreatedListener.groovy | 13 + .../javassist/ClassRedefinitionTester.groovy | 5 +- .../nonjdk/javassist/ClassRedefintions.groovy | 113 +- .../ExprEditorPrintStackTrace.groovy | 23 + .../nonjdk/javassist/LoggigingRedefine.groovy | 22 +- .../jmx/MbeanConnectionCreatorCache.groovy | 60 + .../FieldAccessTester.groovy | 4 +- .../nonjdk/langutils/LangUtils.groovy | 55 - .../nonjdk/log/AddDefaultIgnoreClasses.groovy | 99 ++ .../nonjdk/log/JavaCommonsLogger.groovy | 11 +- .../nonjdk/log/JdkLog2Log4jInit.java | 17 +- .../utilities/nonjdk/log/Log4j1Utils.java | 77 +- .../nonjdk/log/Log4j2PatternLayout.java | 77 +- .../utilities/nonjdk/log/Log4j2Utils.java | 38 +- .../nonjdk/log/Log4jMigrateUtils.java | 4 + .../nonjdk/log/Sl4j2JdkLoggerConverter.java | 13 + .../utilities/nonjdk/log/Sl4jLogger.java | 8 +- .../nonjdk/log/Sl4jLoggerCommon.groovy | 23 + .../nonjdk/log/threadfilter/IfAppender.java | 5 +- .../threadfilter/Log4j2ThreadAppender.groovy | 8 +- .../nonjdk/memorystat/GcInfoBean.groovy | 11 +- .../nonjdk/memorystat/MemoryInfoBean.groovy | 24 + .../memorystat/MemoryInstanceInfoGG.groovy | 3 +- .../memorystat/MemoryStatCollector.groovy | 141 +- .../utilities/nonjdk/net/GetMyHostName.groovy | 16 + .../utilities/nonjdk/net/JrrHttpUtils.groovy | 173 +++ .../nonjdk/net/NetDebugEnable.groovy | 18 + .../utilities/nonjdk/net/ProxyTrackerI.groovy | 16 + .../nonjdk/net/ProxyTrackerStat.groovy | 30 + .../nonjdk/net/RedirectStrategyNone.groovy | 29 + .../BasicCredentialsProviderJrr.groovy | 34 + .../NTLMSchemeFactoryJrr.groovy | 37 + .../net/apachehttpclient/NTLMSchemeJrr.groovy | 49 + .../ProxyAuthenticationStrategyJrr.groovy | 50 + .../net/okhttp/NTLMAuthenticator.groovy | 110 ++ .../nonjdk/net/okhttp/NtlmState.groovy | 17 + .../nonjdk/net/ssl/SslAllTrustManager.groovy | 39 + .../nonjdk/net/ssl/SslChecksDisable.groovy | 43 + .../net/ssl/SslConnectionInspect.groovy | 74 + .../ssl/SslHostNameVerifierAllowAll.groovy | 29 + .../net/ssl/bc/SslConnectionInspectBc.groovy | 61 + .../utilities/nonjdk/packun/Pack.groovy | 3 +- .../utilities/nonjdk/packun/Unpack.groovy | 24 +- .../problemchecker/JustStackTrace.groovy | 12 + .../problemchecker/ProblemCollector.groovy | 66 + .../problemchecker/ProblemCollectorI.groovy | 14 + .../ProblemCollectorIThrowImmediate.groovy | 15 + .../ProblemFoundException.groovy | 29 + .../problemchecker/ProblemHelper.groovy | 32 + .../nonjdk/problemchecker/ProblemInfo.groovy | 22 + .../quickfixsender/JrrQfApplication.groovy | 66 + .../quickfixsender/JrrQfDataHolder.groovy | 71 + .../nonjdk/quickfixsender/JrrQfHelper.groovy | 332 ++++ .../quickfixsender/JrrQfSessionFactory.groovy | 37 + .../nonjdk/quickfixsender/QfColumns.groovy | 12 + .../QfRstaRunnerWithStackTrace.groovy | 424 ++++++ .../nonjdk/quickfixsender/QfRunnerType.groovy | 12 + .../redefineclass/RedefineClassI.groovy | 21 + .../redefineclass/RedefineClassImpl.groovy | 85 ++ .../IteratorServiceLoader.groovy | 154 ++ .../serviceloader/ServiceLoaderFactory.groovy | 55 + .../serviceloader/ServiceLoaderStorage.groovy | 58 + .../GroovySehllSshServiceSettings.groovy | 18 + .../nonjdk/shell/GroovyShellSshService.groovy | 2 + .../shell/console/ConRunner3WithArgs.groovy | 46 + .../GroovyShellRunnerFromConsole.groovy | 4 +- ...GroovyShellRunnerFromConsoleWithMap.groovy | 41 + .../shell/console/ShortcustHelperProp.groovy | 42 + .../shell/core/GroovyShellRunner2.groovy | 2 +- .../nonjdk/sshsup/ConnectionState.groovy | 17 + .../nonjdk/sshsup/FilePermissions.groovy | 48 + .../nonjdk/sshsup/FoundManyException.groovy | 18 + .../sshsup/JcraftConnectopnOpener.groovy | 60 +- .../utilities/nonjdk/sshsup/JrrJSch.groovy | 37 + .../nonjdk/sshsup/JrrJrrKnowHost.groovy | 26 + .../utilities/nonjdk/sshsup/JrrJschIO.groovy | 31 + .../nonjdk/sshsup/JrrJschSession.groovy | 180 +++ .../nonjdk/sshsup/MavericSshSup.groovy | 22 +- .../utilities/nonjdk/sshsup/SftpUtils.groovy | 253 +++- .../sshsup/SshBadExitCodeException.groovy | 14 + .../nonjdk/sshsup/SshCommandExec.groovy | 125 ++ .../utilities/nonjdk/sshsup/SshConSet2.groovy | 3 +- .../utilities/nonjdk/sshsup/SshConSet3.groovy | 25 +- .../nonjdk/sshsup/SshHostKeyExtractor.groovy | 45 + .../nonjdk/sshsup/UserInfoJrr.groovy | 60 + .../nonjdk/sshsup/auth/AuthState.groovy | 23 + .../nonjdk/sshsup/auth/AuthStateEnum.groovy | 13 + .../nonjdk/sshsup/auth/InitAuth.groovy | 41 + .../auth/SshAuthCallParentMethod.groovy | 14 + .../sshsup/auth/SshAuthHandlerJrr.groovy | 56 + .../nonjdk/sshsup/auth/SshAuthType.groovy | 27 + .../auth/UserAuthGSSAPIWithMICJrr.groovy | 28 + .../UserAuthKeyboardInteractiveJrr.groovy | 30 + .../nonjdk/sshsup/auth/UserAuthNoneJrr.groovy | 39 + .../sshsup/auth/UserAuthPasswordJrr.groovy | 45 + .../sshsup/auth/UserAuthPublicKeyJrr.groovy | 50 + .../sshsup/channels/JrrChannelExec.groovy | 52 + .../sshsup/channels/JrrChannelSftp.groovy | 29 + .../sshsup/channels/JrrChannelShell.groovy | 38 + .../channels/JrrJschSessionMethods.groovy | 23 + .../sshsup/channels/JschChannelType.groovy | 68 + .../AnalizeJavaSourceFile.groovy | 3 +- .../staticanalizer/ExpressionFinder.groovy | 2 +- .../str2obj/DateOnlyBackConverter.groovy | 58 + .../nonjdk/str2obj/ListConverter.groovy | 4 +- .../nonjdk/str2obj/RegisterConverters.groovy | 3 +- .../nonjdk/str2obj/types/DateOnlyBack.groovy | 48 + .../utilities/nonjdk/svn/SvnUtils.groovy | 38 +- .../utilities/nonjdk/svn/SvnUtils2.groovy | 107 +- .../utilities/nonjdk/swing/MyTextArea.groovy | 23 +- .../utilities/nonjdk/tcpmon/AdminPage2.groovy | 6 - .../utilities/nonjdk/tcpmon/Connection.java | 11 +- .../utilities/nonjdk/tcpmon/Listener.java | 17 +- .../nonjdk/tcpmon/RestrictedTextField.java | 3 +- .../nonjdk/tcpmon/SlowLinkSimulator.java | 8 +- .../utilities/nonjdk/tcpmon/SocketRR.java | 20 +- .../utilities/nonjdk/tcpmon/SocketWaiter.java | 7 +- .../nonjdk/timer/AdjustPeriodTimer.java | 10 + .../utilities/nonjdk/timer/CronTimer.java | 10 +- .../utilities/nonjdk/timer/JrrTimerTask2.java | 2 +- .../utilities/nonjdk/timer/Timer.java | 51 +- .../utilities/nonjdk/timer/TimerPeriod.java | 24 +- .../nonjdk/timer/TooShortPeriodListener.java | 3 + .../nonjdk/timer/WaitNotifyMethods.java | 11 +- .../nonjdk/timer/WaitNotifyMethods2.java | 28 + .../nonjdk/winutils/WinCmdUtils.groovy | 75 +- .../nonjdk/winutils/WinCmdUtils2.groovy | 4 +- .../nonjdk/ziputil/FileLineHandler.groovy | 68 + .../nonjdk/ziputil/FileLineHandlerBase.groovy | 85 ++ .../ziputil/GzipLineHandlerSupport.groovy | 39 + .../nonjdk/ziputil/LineHandlerSupport.groovy | 14 + .../ziputil/StdLineHandlerSupport.groovy | 35 + .../swingfind/SwingComponentFinder.groovy | 4 +- .../test/DiffClassloaderServiceRegister.java | 4 +- 691 files changed, 29639 insertions(+), 3325 deletions(-) delete mode 100644 InvokationFramework.iml create mode 100644 resources/icon/idea/reload_class.png create mode 100644 resources/tcpmon/Quickfixj_sample.groovy create mode 100644 resources/tcpmon/extMethodTester.groovy create mode 100644 richNpe/antimodule64.dll create mode 100644 richNpe/richNPE64.dll create mode 100644 richNpe/richNPE64.so create mode 100644 src-archiver/net/sf/jremoterun/utilities/nonjdk/archiver/JrrCommonsArchiver.groovy create mode 100644 src-archiver/org/rauschig/jarchivelib/CommonsArchiverOriginal.groovy delete mode 100644 src-common/net/sf/jremoterun/utilities/javassist/ClassRedefintions.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/BaseDirSetting.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/ConsoleTextFunctionPrefix.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/FileEnumContains.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/FileUtilsJrr.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/NpeFixAgent.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmConsoleDecompiler.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmConsoleDecompilerVisitor.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmUtils.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/ClassRemapperConst.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyClassVisitor.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyMethodClassVisitor.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyMethodVisitor.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/MethodRemapperConst.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/SimpleRemapperUsed.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/AccessClassVisitor.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/AccessModifController.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/DirAccessModifController.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/JarAccessModifController.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/JrrMethodVisitor.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/ZipEntryCallbackAm.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/usedclasses/UsedClasses.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/AsmByteCodeVerifier.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/DirByteCodeVerifier.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/JarByteCodeVerifier.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/JrrAsmVerifier.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/AndroidArchive.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/GeneralBiblioRepository.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/UserBintrayRepo.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorEnumConverter.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddFileWithSourcesDummy.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddToAdderSelf.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/BinaryWithSource3.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/UnzipRef.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/UrlRef.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ZeroOverheadFileRef.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/InitLogTracker.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/InitLogTrackerMBean.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/LogItem.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AllMavenIdsRefs.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AsmOw.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/CustomRefsUrls.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitMavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitSomeRefs.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitlabLibsMavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Gradle5MavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterJarRefs2.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/KafkaMavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/KotlinMavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MaryDependentMavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MaryTtsMavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenIdAndRepoCustom.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenMavenIdRandom.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenMavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenResolverMavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/NettyMavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Okhttp3MavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Pi4j.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/TwelvemonkeysImageioMavenIds.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/BintraySearch.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/BintraySearchResult.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenElementsGet.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/enumutils/EnumCustomNameResolver.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/enumutils/EnumNameProvider.groovy delete mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/CloneGitRepo2.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/CommitApplier.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/CommitIdCanonicalTreeParser.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffApplier.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffApplierFactory.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffEntryUtils.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffFormatterJrr.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffWriter.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/GitProgressMonitorJrr.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRemoteFind.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRepoCheckoutFork.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRepoUtils.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/GitSpecRef.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/GitToSvnConverter.groovy delete mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/JrrGitSshFactory.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/RemoteSessionGitJrr.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnSpecRef.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/langutils/JavaStartTime.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/langutils/LangUtils.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/langutils/NativeLibraryLoaderChecker.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/langutils/ObjectStringComparator.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/FilterOutputStreamJrr.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/NativeProcessResult.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/NonClosableStream.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer7Sub.groovy create mode 100644 src-common/net/sf/jremoterun/utilities/nonjdk/swing/QrCodeCreator.groovy create mode 100644 src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/classpathchecker/EclipseClassPathChecker.java create mode 100644 src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/customrunners/CustomRunnersView.java create mode 100644 src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/init/AddIgnoreClasses.java rename src-eclipse-showcmd/{nik/git/forcepush => net/sf/jremoterun/utilities/nonjdk/eclipse/misc}/MyIDEWorkbenchErrorHandler.java (78%) create mode 100644 src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/misc/SetEclipseLogHandler.java create mode 100644 src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/proxy/NoProxyEclipseProxyData.java create mode 100644 src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/userlibconfig/UserLibraryConfigurator.java create mode 100644 src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/workingset/WorkingSetUpdate.java delete mode 100644 src-eclipse-showcmd/nik/git/forcepush/SetEclipseLogHandler.java create mode 100644 src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/JrrEclipseStartupSettings.java create mode 100644 src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/SvnAdapterManagerJrr.java rename {src-eclipse-showcmd => src-eclipse-svn}/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/SvnUpdater2.java (100%) create mode 100644 src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/ActivatorJrr.java create mode 100644 src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/SvnClientJrr.java create mode 100644 src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/SvnKitClientAdapterJrr.java create mode 100644 src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/JavaVersionChecker.groovy create mode 100644 src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ChildFileLazy.groovy create mode 100644 src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/FileChildLazyRef.groovy create mode 100644 src-githubutils/net/sf/jremoterun/utilities/nonjdk/git/hub/GitHubUtils.groovy create mode 100644 src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitLabUtils.groovy create mode 100644 src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitlabMrMonitor.groovy create mode 100644 src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitlabPipelineRunner.groovy create mode 100644 src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/AddToClassloader.groovy create mode 100644 src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/SetCallerClass.groovy create mode 100644 src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/JrrText2Speech.groovy create mode 100644 src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/idea/IdeaClasspathImportFailed.groovy create mode 100644 src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/idea/IdeaClasspathImportedFine.groovy create mode 100644 src-idea-github/net/sf/jremoterun/utilities/nonjdk/idea/github/IdeaGitgubAddRepo.groovy create mode 100644 src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBuildRunnerSettings.java create mode 100644 src-idea-launcher/org/jetbrains/jps/cmdline/LauncherOriginal.java create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/CompletionProviderCommon.java create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/JmxLocalhostConnections.groovy create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/ReloadClassConnectionPanel.groovy create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/ReloadClassSettingsI.groovy create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/SpecialMethodName.groovy create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleEnum.groovy create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/FieldResolvedDirectly.groovy create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/FieldResolvedDirectlyMoreComplex.groovy create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaAddFileWithSourcesFactory.groovy create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaRuntimeClassRefrences.groovy create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaRuntimeClasspath.groovy create mode 100644 src-idea/idea/plugins/thirdparty/filecompletion/share/IdeaReBuilder.groovy create mode 100644 src-idea/net/sf/jremoterun/utilities/nonjdk/idea/CurrentIdeaVersionUtils.groovy create mode 100644 src-idea/net/sf/jremoterun/utilities/nonjdk/idea/IdeaMavenRepoParser.groovy create mode 100644 src-idea/net/sf/jremoterun/utilities/nonjdk/idea/ReloadClassIdeaToolbar.groovy create mode 100644 src-idea/net/sf/jremoterun/utilities/nonjdk/idea/classpathtester/IdeaClassPathRuntimeTester.groovy create mode 100644 src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/AddFilesToClassLoaderGroovyIdea.groovy create mode 100644 src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClassLoadWarmup.groovy create mode 100644 src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaClassPathHookV2.groovy create mode 100644 src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaProxyDisable.groovy create mode 100644 src-idw/net/infonode/properties/propertymap/JrrIdwPropertyMapManager.groovy create mode 100644 src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwFrameCreator.groovy rename src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/{MyDockingWindowTitleProvider.java => MyDockingWindowTitleProvider.groovy} (82%) create mode 100644 src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/QrCoderPaneCreator.groovy rename src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/{Shortcuts.java => Shortcuts.groovy} (52%) create mode 100644 src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTable.groovy create mode 100644 src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTableColumns.groovy create mode 100644 src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTableWrapper.groovy create mode 100644 src-java8/net/sf/jremoterun/utilities/nonjdk/classpath/java8/VmUtilities.groovy rename {src/net/sf/jremoterun/utilities/nonjdk/log => src-java8/net/sf/jremoterun/utilities/nonjdk/log/java8}/JdkCoreMethods.groovy (85%) create mode 100644 src-jsshext/com/jcraft/jsch/ChannelExecOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/ChannelForwardedTCPIPOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/ChannelSessionOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/ChannelSftpOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/ChannelShellOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/ChannelX11Original.groovy create mode 100644 src-jsshext/com/jcraft/jsch/HostCheckResultEnum.groovy create mode 100644 src-jsshext/com/jcraft/jsch/JrrJschSessionOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/JrrJschStaticUtils.java create mode 100644 src-jsshext/com/jcraft/jsch/JrrKnowHostOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/JrrSchSessionLog.groovy create mode 100644 src-jsshext/com/jcraft/jsch/JschIOOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/SshCmds.groovy create mode 100644 src-jsshext/com/jcraft/jsch/UserAuthGSSAPIWithMICOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/UserAuthKeyboardInteractiveOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/UserAuthLoggingInterface.groovy create mode 100644 src-jsshext/com/jcraft/jsch/UserAuthNoneOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/UserAuthNoneWithLogging.java create mode 100644 src-jsshext/com/jcraft/jsch/UserAuthPasswordOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/UserAuthPasswordWithLogging.java create mode 100644 src-jsshext/com/jcraft/jsch/UserAuthPublicKeyOriginal.groovy create mode 100644 src-jsshext/com/jcraft/jsch/UserAuthPublicKeyWithLogging.java create mode 100644 src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/BasicCredentialsProviderMavenJrr.groovy create mode 100644 src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/JrrMavenDownloadHttpHandler.java create mode 100644 src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/JrrMavenHttpUtils.groovy create mode 100644 src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/NTLMSchemeFactoryMavenJrr.groovy create mode 100644 src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/NTLMSchemeMavenJrr.groovy create mode 100644 src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/ProxyAuthenticationStrategyMavenJrr.groovy create mode 100644 src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/JrrMavenCli.java create mode 100644 src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/JrrMavenCliWrapper.java create mode 100644 src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/utils/JrrClassWorldListener.groovy create mode 100644 src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/utils/RealmDumper.groovy create mode 100644 src-maven-launcher/org/apache/maven/cli/CliRequestPublic.java create mode 100644 src-maven-plugin-ext/net/sf/jremoterun/utilities/nonjdk/maven/pluginext/JrrMavenPluginExt.java create mode 100644 src-maven-plugin-ext/net/sf/jremoterun/utilities/nonjdk/maven/pluginext/NoopMavenModelValidator.java create mode 100644 src-maven/net/sf/jremoterun/utilities/nonjdk/maven/MavenRunner.groovy create mode 100644 src-maven/net/sf/jremoterun/utilities/nonjdk/maven/MavenRunnerLauncher.groovy create mode 100644 src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenHttpTransporterFactoryJrr.groovy create mode 100644 src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenUploader.groovy create mode 100644 src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenUploaderMavenId.groovy create mode 100644 src-maven/org/apache/maven/repository/internal/MavenSettingsJrr.groovy create mode 100644 src-maven/org/apache/maven/repository/internal/RemoteSnapshotMetadataGeneratorJrr.java create mode 100644 src-maven/org/apache/maven/repository/internal/RemoteSnapshotMetadataJrr.java create mode 100644 src-maven/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactoryJrr.java create mode 100644 src-maven/org/eclipse/aether/transport/http/HttpTransporterJrr.java create mode 100644 src-netbeans/net/sf/jremoterun/utilities/nonjdk/netbeans/heapwalker/OpenInIdeHeap.groovy create mode 100644 src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/LogImprovedJarManager.groovy create mode 100644 src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/OpenInBrowserLinkGeneratorResult.groovy create mode 100644 src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RSyntaxTextAreaCodeAssistUndoFix.groovy create mode 100644 src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/TextAssociatedLinkGenerator.groovy create mode 100644 src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace3.groovy create mode 100644 src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/StopRequestIndicator.groovy rename {src => src-timmoson}/timmoson/client/ClientParams.java (81%) rename {src => src-timmoson}/timmoson/client/ClientSendRequest.java (98%) rename {src => src-timmoson}/timmoson/client/ClientStaticUtils.java (90%) rename {src => src-timmoson}/timmoson/client/DGCMonitor.java (94%) rename {src => src-timmoson}/timmoson/client/ProxyCall.java (100%) rename {src => src-timmoson}/timmoson/client/ProxyCallDiffClassloader.java (100%) rename {src => src-timmoson}/timmoson/client/ProxyCallInvocation.java (96%) rename {src => src-timmoson}/timmoson/client/RequestInfoCleint.java (84%) rename {src => src-timmoson}/timmoson/client/TcpSessionClosedListener.java (100%) rename {src => src-timmoson}/timmoson/client/TimmosonSessionStore.java (100%) rename {src => src-timmoson}/timmoson/client/TimmosonSessionStoreAndBuilder.java (91%) rename {src => src-timmoson}/timmoson/client/TimmosonSessionStoreSimple.java (100%) rename {src => src-timmoson}/timmoson/client/telnet/TelnetTimmosonSessionStoreSimple.java (100%) rename {src => src-timmoson}/timmoson/common/CallBackSession.java (77%) rename {src => src-timmoson}/timmoson/common/CallInfoServer.java (100%) rename {src => src-timmoson}/timmoson/common/ClientInfo.java (71%) rename {src => src-timmoson}/timmoson/common/TcpCallCommon.java (78%) rename {src => src-timmoson}/timmoson/common/debug/LocalSessionNotifier.java (100%) rename {src => src-timmoson}/timmoson/common/debug/LocalSessionRequestBean.java (82%) rename {src => src-timmoson}/timmoson/common/debug/TcpSessionNotifier.java (100%) rename {src => src-timmoson}/timmoson/common/debug/TcpSessionTrackerBean.java (87%) rename {src => src-timmoson}/timmoson/common/remoterun/IfRegister.java (93%) rename {src => src-timmoson}/timmoson/common/remoterun/InvokactionRemoreRun.java (99%) rename {src => src-timmoson}/timmoson/common/sertcp/Consts.java (100%) rename {src => src-timmoson}/timmoson/common/sertcp/IfSharedObjects.java (90%) rename {src => src-timmoson}/timmoson/common/sertcp/MakeProxyDiffClassLoader.java (97%) rename {src => src-timmoson}/timmoson/common/sertcp/ProxyCallInvocationDiffClassloader.java (92%) rename {src => src-timmoson}/timmoson/common/sertcp/RemoteService.java (88%) rename {src => src-timmoson}/timmoson/common/sertcp/TcpSession.java (91%) create mode 100644 src-timmoson/timmoson/common/sertcp/TimmosonSettings.groovy rename {src => src-timmoson}/timmoson/common/telnet/TelnetRemoteService.java (93%) rename {src => src-timmoson}/timmoson/common/telnet/TelnetSession.java (96%) rename {src => src-timmoson}/timmoson/common/transferedobjects/JmxServiceId.java (100%) rename {src => src-timmoson}/timmoson/common/transferedobjects/RemoteObjectClient.java (77%) rename {src => src-timmoson}/timmoson/common/transferedobjects/RemoteObjectServer.java (77%) rename {src => src-timmoson}/timmoson/common/transferedobjects/ReponseBean.java (80%) rename {src => src-timmoson}/timmoson/common/transferedobjects/RequestBean.java (90%) rename {src => src-timmoson}/timmoson/common/transferedobjects/ServiceId.java (100%) rename {src => src-timmoson}/timmoson/common/transferedobjects/SessionServiceId.java (100%) rename {src => src-timmoson}/timmoson/common/transferedobjects/StaticServiceId.java (100%) rename {src => src-timmoson}/timmoson/localcall/CallInfoServerCallBack.java (80%) rename {src => src-timmoson}/timmoson/localcall/LocalCallUtils.java (91%) rename {src => src-timmoson}/timmoson/localcall/LocalSession.java (82%) rename {src => src-timmoson}/timmoson/server/GetReponseHandler.java (100%) rename {src => src-timmoson}/timmoson/server/ServerUtilsStatic.java (97%) rename {src => src-timmoson}/timmoson/server/ServiceCallServerInvoker.java (97%) rename {src => src-timmoson}/timmoson/server/ServiceCallServerInvokerDebug.java (95%) rename {src => src-timmoson}/timmoson/server/ServiceCallServerInvokerDebugFile.java (90%) rename {src => src-timmoson}/timmoson/server/ServiceInfo.java (80%) rename {src => src-timmoson}/timmoson/server/ServiceLocator.groovy (88%) rename {src => src-timmoson}/timmoson/server/ServiceSupport.groovy (100%) rename {src => src-timmoson}/timmoson/server/TcpCallInfoServer.java (84%) rename {src => src-timmoson}/timmoson/server/TcpServiceObject.java (75%) rename {src => src-timmoson}/timmoson/server/TcpSocketLlistener.java (94%) rename {src => src-timmoson}/timmoson/server/service/DefaultService.java (100%) rename {src => src-timmoson}/timmoson/server/service/TcpService.java (88%) rename {src => src-timmoson}/timmoson/server/service/TestService.java (100%) rename {src => src-timmoson}/timmoson/server/telnet/TelnetRequestBean.java (76%) rename {src => src-timmoson}/timmoson/server/telnet/TelnetServerUtilsStatic.java (97%) rename {src => src-timmoson}/timmoson/server/telnet/TelnetSocketLlistener.java (100%) rename {src => src-timmoson}/timmoson/testservice/CallbackService.java (64%) rename {src => src-timmoson}/timmoson/testservice/SampleService.java (89%) create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/VersionComparator.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/antutils/JrrAntUtils2.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElement.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElement2.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElements.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/apprunner/RunProgramOnStart3.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/cacheddata/CachedData.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/AddDirectoryWithFiles.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/BintrayJarDownloader.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/AddedLocationDetector.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/AllClasspathAnalysis.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/DumpLoadedClasses.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/DuplicateClassesDetector.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/GetClassesFromLocation.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/UsedByAnalysis.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrJarRunner.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrSvnConsole.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/SrcDirFinder.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/refs2/EclipseLatest.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClassPathTesterHelper2.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/JavaToolsJarTester.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ProblemInfoClass.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/classuggest/GetListOfClasses.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/compile/JeditTermClassChecker.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/compile/auxh/AddGroovyToParentClResolver.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/ConsoleProgramEnum.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/GradleWrapperRunner.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyBC2.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyChecker2.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoader3.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderAny.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderJsch.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderSshtools.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/CertificateChecker.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/CipherMode.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/EcPrivateKeyChecker.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/EncDec.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/EncInfo.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/JavaSecurityProviders.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/crypto/KeyType.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/cvsutils/CsvNormalizer.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/disktest/DiskPerformanceTester.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/disktest/DiskPerformanceTesterWrapper.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/fileloayout/GitWinFilesLayout.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/generalutils/LogCounter.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/git/JrrGitSshFactory.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/groovy/ExtentionMethodChecker.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/groovy/ExtentionMethodChecker2.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ivy/IvyDepResolver3.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ivy/IvyDownloadFromSpecifiedSource.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ivy/JrrDependecyAmenderDefault.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ivy/JrrIvyURLHandler.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ivy/ManyReposDownloaderImpl.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ivy/MavenManyReposDownloader.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ivy/OnRepoCreatedListener.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/javassist/ExprEditorPrintStackTrace.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/jmx/MbeanConnectionCreatorCache.groovy delete mode 100644 src/net/sf/jremoterun/utilities/nonjdk/langutils/LangUtils.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/log/AddDefaultIgnoreClasses.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/log/Sl4j2JdkLoggerConverter.java create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/log/Sl4jLoggerCommon.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryInfoBean.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/GetMyHostName.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/JrrHttpUtils.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/NetDebugEnable.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/ProxyTrackerI.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/ProxyTrackerStat.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/RedirectStrategyNone.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/BasicCredentialsProviderJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/NTLMSchemeFactoryJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/NTLMSchemeJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/ProxyAuthenticationStrategyJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/okhttp/NTLMAuthenticator.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/okhttp/NtlmState.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslAllTrustManager.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslChecksDisable.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslConnectionInspect.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslHostNameVerifierAllowAll.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/net/ssl/bc/SslConnectionInspectBc.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/problemchecker/JustStackTrace.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollector.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollectorI.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollectorIThrowImmediate.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemFoundException.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemHelper.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemInfo.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfApplication.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfDataHolder.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfHelper.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfSessionFactory.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfColumns.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfRstaRunnerWithStackTrace.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfRunnerType.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/redefineclass/RedefineClassI.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/redefineclass/RedefineClassImpl.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/serviceloader/IteratorServiceLoader.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/serviceloader/ServiceLoaderFactory.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/serviceloader/ServiceLoaderStorage.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/shell/GroovySehllSshServiceSettings.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/shell/console/ConRunner3WithArgs.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/shell/console/GroovyShellRunnerFromConsoleWithMap.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/shell/console/ShortcustHelperProp.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/ConnectionState.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/FilePermissions.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/FoundManyException.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJSch.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJrrKnowHost.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJschIO.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJschSession.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshBadExitCodeException.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshCommandExec.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshHostKeyExtractor.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/UserInfoJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/AuthState.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/AuthStateEnum.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/InitAuth.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthCallParentMethod.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthHandlerJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthType.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthGSSAPIWithMICJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthKeyboardInteractiveJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthNoneJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthPasswordJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthPublicKeyJrr.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelExec.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelSftp.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelShell.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrJschSessionMethods.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JschChannelType.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/str2obj/DateOnlyBackConverter.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/str2obj/types/DateOnlyBack.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/timer/WaitNotifyMethods2.java create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ziputil/FileLineHandler.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ziputil/FileLineHandlerBase.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ziputil/GzipLineHandlerSupport.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ziputil/LineHandlerSupport.groovy create mode 100644 src/net/sf/jremoterun/utilities/nonjdk/ziputil/StdLineHandlerSupport.groovy diff --git a/InvokationFramework.iml b/InvokationFramework.iml deleted file mode 100644 index f74432c3..00000000 --- a/InvokationFramework.iml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/groovycustom/src/net/sf/jremoterun/utilities/nonjdk/langi/JrrGroovyStaticCompilationVisitorFactory.groovy b/groovycustom/src/net/sf/jremoterun/utilities/nonjdk/langi/JrrGroovyStaticCompilationVisitorFactory.groovy index 854737db..636c99d8 100644 --- a/groovycustom/src/net/sf/jremoterun/utilities/nonjdk/langi/JrrGroovyStaticCompilationVisitorFactory.groovy +++ b/groovycustom/src/net/sf/jremoterun/utilities/nonjdk/langi/JrrGroovyStaticCompilationVisitorFactory.groovy @@ -14,21 +14,23 @@ class JrrGroovyStaticCompilationVisitorFactory { private static final Logger log = Logger.getLogger(JrrGroovyStaticCompilationVisitorFactory.name); - public static boolean useImprovedStaticCompiler - public static String useImprovedCompilerProp ="groovy.useImprovedCompiler" + public static boolean useImprovedStaticCompiler = true; + public static String useImprovedCompilerProp = "groovy.useImprovedCompiler" public static boolean loadJrrClassUtilsTryied = false public static ClassLoader cl = JrrGroovyStaticCompilationVisitorFactory.getClassLoader() - static { + + static boolean getPropValueSetting() { String propsValue = System.getProperty(useImprovedCompilerProp); - boolean value4; if (propsValue == null) { - value4 = true - } else { - value4 = "true".equalsIgnoreCase(propsValue) + return true } - useImprovedStaticCompiler = value4 + return "true".equalsIgnoreCase(propsValue) + } + + static { + useImprovedStaticCompiler = getPropValueSetting() } diff --git a/groovycustom/src/net/sf/jremoterun/utilities/nonjdk/langi/JrrStaticCompilationVisitor.java b/groovycustom/src/net/sf/jremoterun/utilities/nonjdk/langi/JrrStaticCompilationVisitor.java index f2763ab0..0dd51c1e 100644 --- a/groovycustom/src/net/sf/jremoterun/utilities/nonjdk/langi/JrrStaticCompilationVisitor.java +++ b/groovycustom/src/net/sf/jremoterun/utilities/nonjdk/langi/JrrStaticCompilationVisitor.java @@ -20,11 +20,7 @@ import org.codehaus.groovy.transform.sc.StaticCompilationVisitor; import org.codehaus.groovy.transform.stc.Receiver; -import java.util.Collection; -import java.util.IdentityHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.logging.Logger; @CompileStatic @@ -82,11 +78,14 @@ public void visitBlockStatement(BlockStatement block) { } super.visitBlockStatement(block); if (block != null) { - visitClosingBlock(block); + visitClosingBlockJrr(block); } } - public void visitClosingBlock(BlockStatement block) { + public void visitClosingBlockJrr(BlockStatement block) { + if(enclosingBlocks.size()==0){ + throw new NoSuchElementException("collection is empty"); + } BlockStatement first = enclosingBlocks.removeFirst(); boolean found = blockStatements2Types.containsKey(first); if (found) { diff --git a/resources/icon/idea/reload_class.png b/resources/icon/idea/reload_class.png new file mode 100644 index 0000000000000000000000000000000000000000..8cc04036d2c7dbde7c836b0db801d80df1f65372 GIT binary patch literal 519 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

Sy^#XR0~#35W+Uw>CGp0-|z+p7*Y$Gzes3qT&_ zaBE<6nOeioEuk|NoUwK2#H6UKqZcQ3Rt)BF1a)8_*DZHDEN8UC_586qOUWK}oV)EY z&jz_m<|%TaPAGs`QrBFNM*>Lq~&b1U)he75NEk_uyf+?P;V=_efwocZp0Qp z?IUoA1iUh>*%L*2kzYC6sJb)^B`Dj z(#U*e&LrpcAcvE~Ih+#B;nZ*rr>Pu{lnpph>+E0NxyW)JwMRWaayA0Kna&L7Mlg!& zMdvV`4Z2=*4p-SI=6lo55fUgW>(>G%Th5UZHMaPC(vOlrS@GjMigL6BCKTUF%1jBA z7yp!jDhW&7WWB&@d$uLV_P=|Ae6(OG1t#%rI52x;nd3nilYNUxC)ZX9U4%3>I z=5Y|r<^XT?XEq*6hlyqZ%_ z1D5lI-Gdxtn2k_X=NVQxa~*3l8q-qvXUKJl#}nNB$U(5UQo+`#Gxbk2Cc=O-t)1eI zCB!h#ITs8bdyQo{7PY)HC*K?5XmGZIqo_>2oYqtGEpP80>J0HUI!C{Z&H^T#ml(Fg z*yP*@#xhl<$2uP)FhNymvjoajm9|J=x~kGv3Cs*MV}|9lNmOkRRZ(s^^Chk+A6H>H z$4T6Rd|ajFEReX9^Kp|b=Xi-*nva9_ogi_2`M4?Y4JUCcbdAY@me92u=Sh1%)JTTa zqU$WqGS)fCS;bmAm7T5SeASUlp=GM?U5JC-Ic?B$(kQ(U1?(p~=b|Go((-kOtFF2@ zzqYT*%Z-pGI18O=e}K?lxaou1b?9COeP#bjBX5zGcRJ3;cJ`atPKg~|recwU#m*+_ ze0s!HR4&TBM7YP6MTkhWR1%rh+4uo}=QnmMa;HlyPAzgyalQ+3@!n}P?^DHOT4gvU z*O}{)n|e6Vt+K95MJ%~Fm!Fj@1kNV=-jD<~&L~5<)8oweqY=_;gmm^S;n<{4;j5w6 zX)>HBDt>7kvePetv1Rb!*V*6IksB~qR&j+~NXEDi3WPE4vV^aO1<%<{kgLBvA3xSv z?%cu*$?)!U!GhB8l!LRv;ljUHwh$}Hxj}9|J1ZUT%#1GU8S3uN^`43o-!h^xiV_^H zG)G01?BChH&dW~bneKee`O1q>oy9mnY&lAdNv6EwO&qwKErFuqGj~H^ zl~w}`$J&>n`p>YQrZ2zeI|0EizQDy!c;mofNXa1sC=D(>juk#fg(6gM)_NbSF?BwIi zoJ*W5L6GsL*h$N|R5~R_t;`La+SQlCy};Ak`%#FONj-6Jswwn>rAXfrQlYN&%N=f# zj8?tq8o?_P2gc5~C16H=I3U;07QhQH^V%`W|D$~`a+6_}bkW6GikvGQ`j6y*ynis) z4g?(dvz+fZ;;KiDRlXY^*Y*z@Wx}mgy9C{Y>+OZVFIkpmyS;~!_Am*`xU0TyOTFx8x4+ZNsgY_D*cs!_7 z{w09 zVdZW{clrEov&X)|ve*ZIzsRX)zJkmy3_8SapQTNycY5M4CtV zmwkaCTx<};!4;2k#B(2lk->X{vi#eAPQW%Buw7t>N|V4Oi*n|i6TV@E5<4`I&+aGo zWI(#!Vfd>)m=bvGBA(s6giyumDOL{=LEadw|*<>WSRwvmfF-dy|PaOx$*J)lo_i(gHd!?E%;% z!Tl1=Juc53g}XsBj8zPMy|DkB&|A)pno_DL{rZNtT8Y7N3+D%#VGqS1!;9{mTE>BY z4oxk|OCFHR>?rnb439*{4>eP9o+&hVf{dFr!|r(ojk1V$;&VZ7iVH28bvMPT>qsU$ zx#jvMBoNnWwp|t5vUYe?!Y_xVsU=-K?cKR$axV~JcoDIjTQqx-$$+{fgTYkK5_|^E zdiMo-aI5CsCC1yiq66zloc~Cdk4)UAImg5})v5_A!EoNLId_h6E(}~k1*~^y*3pV} zK>1L&oFD7>om6~Kk?lPgU#pS+otkBokpgAXN~M?OI{JokgL066z2+^<^A6*=OY?Y! zN0*u|TQ#;fpLn-sE*OCsSL}js{E6muW4!38^%CLI-riFK_Md9@OpLvwcUd2_5N%6U zHrEw{MEB@K=~yDua7@1M)qJTK-|}VJ^yHAM-i`qGKF#mM_WWg!NHL6QwR zi5*L_M0vABi#P5pgCzIsB-#)L#!gv7H15vMfcIybcYIomCI)^TAkryru3x<3TF%ck z%RY)_N#|fLYL(QQf-EO#3-y3b;^&jZmLne29D6H{0f0sep${tpU0B|GNHgxG7?COC zxFT=CSzL5`K4ytBauzbz9VY=s7_E~4$OovWWi01^BVfl3_C+L(8+S9VTMJP zv&lJVE4$J|@b}9hj=WPi%lWM{S9p%a-|>C;6B;$kWg!`5h@ZI-f~+Xe;}EaD)S@L~ zi0@n}K-Un6cf3PD;&Vv+b;y+y`Iih~xR9W{yUML_*Wwk`d1-E>m+=-g5pX$-`uAAm)jEP%_?gz6xO1TSOU`1~T%)Eg9!Z z{)H+N6xX{8vzHN(+j?kvEayMY&jfoTv7e7(3r+~3rhTxzW@uSobLVM8odZ~$wNf8S z;!l~_drNR9zLBm;-*^hD&hy!dX?`?kA82lZ7 z1pdUeA;?W>UIp*Puz47wa)x0pjU1RdS#TE<_xk?>ZYgxYD&<5gB7p-f_%g@xdg^`w zewe^7j|41NXhMoG%%|~e_}CdhIZhXa*d8b58~xCn!{dxf-?M6A>ZnxX-&l-o_&dHA zf0BwZ{6RW3I&3UUr!JAi-)7=_M@THUf`*lgULVA^iF(ii+2K&EKJ~I7zCpzQCLq#& zM6#nc^`bc39cUJ$Q2A(y$6aTV#0Lg3&S7|5EHqLc~_N zt(E0+;i}Z#g1&+1Pe;*dMusQTntOpH41vy{ho_aeAo|Tz=3Rd3PWU^1FZ{_@Ul?uv zygE3f!XnpjAXRWx9K6A2L8?{YP9WS_5jeR|ugsg6k$7p&pQkf>tz_wtv9@zVD$!Md z^_Tas#AUMdgA}vPu>PbUrrt);cx9^KH0X~~EUzLRDW!Q!>br;>1Bbj#?6%!dyAR*C~d#*NwFuWEeqHFeJLtU zQ`zjm*xjF^>0D429&Y?RH4%9^xh!JFA55_iSgInUmiXZm&3a#1#9sX(RROE8!bFN0 z`ellSYgO6smi1VQ&2n{FbwXGFcxna;;qn;Gbk_fyx&qXz%aVK5r&8>K*Om?Irk_r+ zV_z5S*-XQJ&oimf`0n*(5d-vWY65b$Asoq;_}dhX(MA&;HEXzXk)oA-BALweFQjNR zH|6C|!z%$Ie{()=I_`c;+?ISC_O$*aaa+q048$ub+LLW%!+ImFKd+`di2Z2dFuLij zUQe;dv+RjsgZ1YWjh$ytoIfwp9N$b$hBg-2;ihaBvoNvVnz|a~44c!T>S_x6j>UL% zCWm*fHm9Axryl-~+3($!l7*~d@x<|A>U9vjVsWwiNovd|kWwtKo!RM02#hV3r^+(v zc?gsh%UfWD5|~gd&uxuKcY{)1{Jov9%dneJrWebbSEcDSpv)|m7pna9JqXkm%X3cq zrGJM&Q?We1^u_e22rMX;2Ztu6Cwz(qQ7jJyO-j#0U}>>D=5u)ZOa%Ih<$0Ky>1z;J zQ7jL}WhJnxSe|>UOaBy<)y48`OH=x<2wYw)FRQerz5haei^Y-riRlUi))tF@_Kx%k z2&^j>r|PGq&qH8+u{c6MEqyxz8;Zqu`HJ-O2y84CZ{ugD|BJvA#o`|P!t_C(LB)#O z(K$MorkfDhTr8fruS~B*U`w%h&%QQ&BLZ8C#k0`b^y3I@D;8%!H>F=i;3HrB_^gwF zW&7fV=XMEswl7X}?!tzf4L$J1`^`N<8*BUGy5@cfmD#>H)P5*E9-I?wU)*8;QbOgn zFRqXOH;wBF)^yt!$JW0|FGOgj?Tahw-%6;~_QiGdW(hUfzPNe*lY|!7zBrhCEqxBs zooxH^WZ;|WwFoV>eR%-z?exzO>a%@uC;N}|8wjnieQ^Q%uXGA-@mATsxN!YXdOw6# z+rGG8wKAk#Zu{ap)y>o+bhYh^o72&muOYP7_QfgbZkgK=T4(#>gR?ZlysWoyS{HRj&y8$D>FYvXr|+fBdoJBPa{<8_~Nnb{LDWPYI1z>Gj>s?2wo=_IKKD@yG%kS zJHB`Xf&IZp^UZuX22O5$H!5wyxEVFOT`$ zp6N%r%N<{y;khfb2BE7RU*6BTH?tn0wT>_E-uz53*Ezm8*nBwiJZS43UmOGcGV?A% z8ysJ}r#zn71)g6vI=*-f{dI8#XzX1<2dHpdrt*zZW_BgYpf*6(Mo1u)9Q5JKfCU!Du|-5(${ zJr$@%MLEthl)2Q6nW>3z4%g<)M!`?&S!r2uZJ)gog@6`l^&K@7FZD zkAi1)%9mG#PH;a$=<<{=FZ{H-`@(t9)#3Ee>_w7(Z8#Qv>k^4w7mh{mdWyuZPx;~{ ztH-SZ-iDMfo~`=bB?xUy`QnZ0boUa3o=ExP!|6=-W`s7SeDTAy%6%50%_(18C0*ct zg3y+fFFuXF>Fxzr30qUXIMBFMN@`om7pD>5b`JyXqm(bs8NTbDK&J|6|BhnR=(X_Qf5~9qy+HO-TFVKIbmC6n=%u z)4uq?xkqTz)4sT_`I$Qvw3%sN{LVZiwA!@Pxhyw7B59k_zBp0(l}p`Ukj`t$WSpe= zUn#$n)4n)EdfJ^2#HDFp+!#G8p+0=iSbWd(E?d%yv@hP4Uv$p^=c=?X-jQE(e}K^H zv@f1L{^CA}(B=4^ossS>_XUKmPW$3Z<{g(7W^LME#xi=}{TFEK(!O|w`A}%<)4urL z{lwi1UUN63eR)69DVU4U#=R-NXZb3_!y!?KM?56E-p>u0 zgQO5S_PC_${n0S;JwnAOV&r*3*V_-VuE)d0cm*B*mXGFJiHem3^>m`^@no>;O*Bj# zc7>RNGE@td8otGFb6gh6CbX8BDo${ zUS02JCK3CbkTfO&`CUWi7%xUvJH)zh$AB&c!SP=rqt5>{!^p8=BBQu&a=nucBgc)2 zjQWxJiwq;jl!=T-oh2W0w_)UXGm%l&e_ZcH!^p8{BBL&zH0bix9H%BS%8VWh<%W@C z*hEHo8U`<68%BkJde#EMD0Qo7#LhQdK` zo+3N;Ncg59bL6YY!HOryE@I`oIrvp%S<;dmXpK0~@Nh`1cw~)3R!LnCcWM;`N1GwC zxLkF;rH0I*up+Z4m9u!)`-UNNY^=y!;78VOHWcxTEUiGq25yqU!`lR|x6yENoE*x5 zR@Ao)nWLi+S=?H=ULj(o2>5zHh%Aj-UKDUWHagdvU^w{>K%7(F25`OQAh{lk#`T&F zKfU_L`Nh*ezEb%4VXk+s;pf;q#INh&ZbRl^U6G}(^k+V6$n+W>B8wAo*W+nU*V|^8 zIH(VaV1~upQ~nRQOTZ*W!$E(XTRcd+UbW%jR3Ofyv$n+WaDou$(Ry;R;o-DF@ra@Z z)vcUSx!#?Iku!=Aqt4G}L*^7CMAljP(2(hpIYw4)nsNRGB-i6fRGbIHzoiH`$q4bk z4vi?~AMngJJoJYg;t>rJAIYwF8Az_j1EQ{Xis9$bLGjC?sq0;1D4eJ$iWq&Zsy{Vk z&RpVx^!C_q4G-rtAs$`K9~v^JG>R3ZA( zb-fP^U0&D~qayJ6r`=u85{p{`04WL1jTDlU1pff&XhY^?DMS{-sd>I?csOYa@vyZ6 z;#@=KEGkBp%_#8PV0bvU3i0ULe9VyLjpF?0NKhAvhmj@5I=Ct0dT$thPRA5n{`2Ku zObNzf{71f?Gd0C1bu2FGT<=Ij=F}}j<^}*#pJ>RO%Z11yLH<0s1uD8rEajL4I#CNdkecMpz;8#(^Dv7^e*Lw=FuE%rcu6Mg(rJLRmt9b2o zy?+TSkAh=(Y*;zrRjg9h*Fg(FhQAl}Wt{UWa^C5o>+NgE^em{z;$zVD=wHP3W*RzO zZH6);o;O{OCL3d4!^GLLViF6X4f+L!%;|H8thPbJC`1bnDc!JePMHZf)FMlgW~HUpY&&b}Uy9W?^KdZ#SJ`Ey4wa3RHQiJHt%+5J*cW`tBqeP9*_F6a zW~C;78H$x!v+nFlT(M!qR90MS&Dygobs8&mn5xT@A!Qn!!T*A*n&}YcGG<~z?hC-TB6uyboZcuM5RFyJzPiq>T z+Lr@#W4RJHU4&5_W4mJF4x=W)=RNH>s(8i#9$d=xE)H(fVTR$l?R`VYBd+&Nn@pJ)j+SEU6c3>R4+U-+}xqAo_I1^Wco# zf0t-E9VX!CMZwRHf?tpa=gXC|0a32OX9PKC>}iSMX9eJr)w6XF<-oT(uSA-YbvaB8 z&=~u>7#gb-Ek)^Qt`91MCp~F@Sm25_prQvoF6T*6U$xq@J_OL(VImlN5H>`^T636O z*gmE}sew0x?MFe*E#ShOKwbz_bqo@gYsiT~t{J;H203F{=Q5nED&RyN8MUU3KEbjs z0@JpMs`94<$r*cpko4mP6Dxw+0zx?4~$i@4{0o`@)n~c$DDa(q29{h&W~7iuOFby?+TZ z{f!ik20+Hihr`+rbq`whYMpGUHEmBweIM8-YpEzD`Ja6qV-MXeRxCI$dd3-+eNIXl zV(&0s(?d`f3)=J&%RW~J(a>%iWm(MtS+C&_3g8)=i@{q*Tv1?IXCZc@F4cnre#VL# z>Kam#_tBy}_)?#Todujx}*S9UACAbfCZEP`M9q=rWu;I(_Qo zLy#ti|MbKC0Co`$nL4q2V)-Ezhj#Q29=fEXgNObnc3A(Xv{q56s`F>`=ibe}*mkLP z@NrSl-P^OIO#TevmA)moxB*WBIA7#t@)Sm-(BSdd@Zua#nxVtCQl}Gw!G-(NusQ_; zOYxX(Sp+66q;y6g(+ZOR&cHtfZUQXAQ6+UfWSzYfAgA+d8hb7u$^wRd8Md~t1&;67e*)hEJE*f|3w52{V(*R0z;qpdcT#nxX}ZEj%PkhELJl!lhegiq_7M0B zgPOm?K31wRfc>$mV=JTX_v1RQPK!I4(~xvDE=ko_=U|Uq=O^}Nf}LL9-m_##6yT>e zRSr?r^x?ruyhmaj#w_Y=5~h143VT)x$GOkG6firN!3{(OK9-q->fwaD1Oa9u9<`@| z?kNR)OjT^*>G`_;m8wn@3I;g%Ta3K89`)2o7erddm<|B(w+mK@aJ?P$;jM5Czm6)X zna0p0U!4!{Bnk%!jB`DHIX1rJ?-Ph|Y%h>0?LB=TVt2~rObsu>k!+-R8nG!j>}sf~ zZ?;mi-V?Bo@V6+1(eJL(%y!EysBVH|Me+0lLd{%|c3;rZH;4!5tW=htV(s42wM2rm znIv)+9MAXjtW>> zoNg(ZgWp3&T#xO?kWN>PD04VTCbG}O&SC5r7C6rj6kF;2@gH#Ybe^u-TBeBv9V3k` zbF7Z(8#E0e)68}NroKVb6f!Nec8FTi-MdgO4sDiyX#n47x$}JRScObuWO<5Y-)9 zhNv{-Q*{h4;6Kx=8LqBxVa&-Ab2VdT&ueAO5{bDLF^-pB)H{SnSKtpRElo@ZvEv4E z=@_>7zu{jZlqE2*5?5jR`@6evNul8Omq1c+xO&rX72Lt{9czjS!=MhUV4Q09p~&S{ zfo~s<0fXyR$zMtdQsFZC5^(HmpCq&n`Af@UI56nslOR^XK>}i;PY>e1EJ;m#-;!k< zj~7(h6lP*iH__8k%J{8O>ODQZjGEb&0A)UxmcMS%M-l|&qI!g-~rSK+@x$bzWI zIXu+R(gh&o0PTw}}H`dX}q$-%R6TF3I+sDmWcvvEls-<@&N34gy=U zR-sj#uX&ZFn!0&;EPEKaD!`%wFnd;^6XG&H?v#GOwPs-|M6JoruR~rHv8fRrZI90> zv9p@%=G3+}z_F!OnEqTTn9*>mOemGYtZr+@b18XGw_$E~7l&KiM>Nok(IGxj?>xlLaZ-ZzjfwL}V++uCiIZowHN#V@dJjOH zi^6R_9;PWQiZcfJ4TNIi9%5>#&t{uK-@Dr|n#u|Me`*oChdJ;tOwFw0^TkjcB8vM{ zcx=om8NtVtgm`M}W@Ve<$1>E$_DCepu4-v*nGEfwUR#BwA*O10-45B!*5;~)7UdPW z5YE#A z=e5-jv1sC~w$@f?SYC1V3GqnvX%0PDEgT=BOBu)LWg$Af=z|A!h^Z)BE*|>;r=1|Ecm<4HivtL0}`lc9(?TpJ~ow%T)96&}1@J|z`wU*0a8 zk_xs%w#%laPO=IoZkJC<1>2$9Wm8hYRvu!*t1EPxOtYD7#nUCIgS-w`Br?Jsa${>N z?7V5umD^{-xTrn?C-SLQu7x9`R^gOHKAJpf=Ry9aCi0=rpB?3! zHX;bwd(ZfdO4WJG0;Un_~xHR8Z;SnQq2B?bj$dNh8 z0RQOO>bX|oQ6sbAofh#%t}Oo1J7QEueP$w?^kJ&@TQI_ws;?TE6BbIGqZiH^nMc)o zpqSMobA~^+W@NS+_#b;o_3vj*pZ9srsZ-~isyg+ax1Qq+v)+~SxQBA`9A7yPy>!uO;-P%vGT3+r zv)O$sv)yx0gSvm^9PSyY90M!oXzP~SIGoA$^k%TP-5IFQ+m}9`)wJ1NWbkPz-aa1N@7 z-EAUrQ)x~g>PoNu*r*5Z=Pw8(;>I~L+>7aDml_r1Vz`+xo&E5z%^}^7oQwR0j3Qsw zoYz21ht-VwMT}v;=*oM#Q$m*EZ5^E*YKodwTJIuq3xhGk&7A7RP5`R;?TtD_WQ=i~ ziLCunPkQjfU9{7tyfDr(rrOd{Z9;|Z3b6Y{2YPgzF=#Ih?1SOHu~Mgx;$Afoz>#}d z>0)w>B2Tv++gp+c2rpG5Z5cd1CmF*B(w0Md|Ch)VW3~<9C46)MO`zTcL}Z$wLmjPQ{#}!ZL^1;lu%uv7EpSLoO+E6ZQH#xQi>45tt(=$4v{2S*Kb%=7ivnjQejP1wD zC*?bwm!bAOwfoK{-l~au0_Q2}oMyNO!)70}ae?xg&1iyKgoiNeCEyLF1HD1_OS^x(tTF2!ztZ>uaQ8g>{N8HI0= zo-j0=*R;(TsgtlrUy>_L=8m$Fk);EC-WEu1Sr8cVD>Mdwrx4|}!^LVx2L zcvPM&0liA0VQhSfmPgmj8XDxND5Ln%gQDiP zRk{Sg8E8U|T^zuIIqJQX6E$yL?ZL5a`^8I6<$mVHGE2*69q8m5ooy)7t%jHbuB*|Y zeZEqqtLB{?n8~B@GC3^E({3F#pNr~D8TxX2L1VKqjo~B)?cl|lM6I?TlZ$RH^kD{N zATl^NB~P~{?$05|1W7kwSre;HHFq!uT5Eh73p=!gSrb=Ia(PKGphpEL)VwwrmJ(v3 z=EuP(scRrg1j{%z_IsPZ_WL zXef^?Ae<4gGIW{?*dd_iEj|L&US^gTaap^J-!sNgem>U@iBnNCoz?}DwGUx1qUL)( zYo}T`tU2DG+0b1Xk+CbNhPuCOUaL_IchXoTjUKlK4>7!ZY;kFLxiCR@+?wz@ozZR+ z6zW|2#~DfuO)A!>@=MbLbHh0dbSMgrUmBTfo1dS_E1@q;m_$uvJ(XE6SJ`O)F%exu zflu|cn-Z9xQJ33rm=^`4}Mrm=` z2?jV9xQNzit8+6YQJHfXI?;NKbxuOUManN65Yc3iy;Ve0LH2_pnwECCR-Dxj2N7+! zU$zXbA!pmB(D2T4Lqr=H1iQQh5UJpv%vy=7YfHA#I(=-rA=YaPJqe_MU4C3dH+bzm zb2Fsa8g25LogNp_W(^F^;M!5wVYJ0#h7Qsqo~RAf6lO&9 zs29L+#*KXGk_?@SUg-rXS0^ScbEyASUI?c)i$_`e^3oD!S<$PD(6e*xbLi1)yub*w zk){1wuf1bBH-1h6*Li`yv9meU`g*TbJ-3~M-{1xN5ZWP&YV+DN<9Mjdv?DSy+U`Z< z##k~-hYz4#D#m8Kjno;y$WcP^gPuL78DS_tzO=lM%j$dQnE4JMN&mvZfp>8F)ebL% zu%r!v7;-zz2&Lq1qoP_;;F}Yx=oc!}+Xi3XYDzdhf;E(YgSr=93sFOf-UA{g8Te7F zezc0X`f*4kB;}~6Q--6WUK&trQd#gTMZe^3_i6e?9!od|L<1#gQ~E~wk!kDhY8xJI zJ0sRovP1n|N59EyCigIg6Jb3W`iAH{H>jVd=ywzS9`1sRwo`1T-{fkcvbRuT)Jbin zR5!NFl+ODbDAnFK*e=@W7s}~s>lf|nw{)Y34h_JqWpBaV=`ggZi%e9M!|5hNN4Gd8 z|CQl>J@nJwl$d;E>Ttd5C?^uCCeKDGeG)rUVqrkUD4|+HG)v-{;jV7PL(^~aMh>4O z$I9)L>{T1q_RB!a3_iPvKPo5S%IwTq;#W24nLf=~ zoGEVnc(VrZUQnP{Mte#X|0f@YNrHmZi)H-vEjsTIeU^fF#dv;WkHQTNSX=#gi+x8;B&GZz*`sVOt z$7|W5h<|K{&O%34+aq_4bcp!lJG~H9id>Q+KC??B!`RfsJ&3hi18o!M^NTr1e4Z2W zhqYZfcR0AXCnysx)%Wjp0e>!_d-u6$FSVl6i@)^Q)uHTJe>{Ca=jz9cBN`NKN4mlB zZz@Ozv}QBQm`p8Pq8HAES-BCBh`+G)6L^0~D?;bocn~McIiq-kl3T0goTpBn+I)<2 zI`fO;*hPuPq32-ZoYXsudIlXX$60O56ZyFy))Z%*%unP3S$WRt&rRgVXjBE2cTO?o zl_))w^1XxJ3PgOdRW~s5&#_XV+_tyW_PR(9M+jT^9yiJo`N4MM;lL}=x;N0 zbYTXUuZZ^_(K#^D$W37j+QI}}B!xxnODN)>V))23_H`?ahfpv_HPv=D9EORzH)>e_&!TiRK+3ADC zw-|`c;TCfk@`#AOG=PtLMdBLfNT#gri&WxXAEMuj6Dj6FMkf2xPdsCr5vVDh^)#2+ zuO0P?XH1&wqNah6`~lwa^-rleZYiQW0_uOE1_%v+ z4y*_)<)}F6b*#Ud4M#85D(cU&H3|*(!R1l^5F02S2-!Z#h6!C2a(jdNN7&$?#&G7l z^{-}~P8Gw8+`Oni%sN|F_j>_W9C3&_@QEy|_#M{zwh`28nIByqO@8qr{UD2?evJ9U zyJ$~D)k@!IW_7jz93i{URmmpJc!=_R(6HP?dNE z^KZ)o^ub+H-^`uOwrik$48ThyfG=_Sv9^j`XeYC?ix+2SvitF$?-r8$7dev3P~EYV z{8vfs>utwq>d&0+?-R-2kqb~wRguP8aqleL?sQXDQ;eiA{EPv7L?@ElitLzwz;{+y z!u?>1{uRmJm*j}#WJOT9?6+P02 zHx#*_Gvi+lbsl97hD`(mf zqOvqGI^5^H_oZH@u1AuqMeCS_Ed z7w@_#QunhU5lkVc@rknRLOYE1LT`#q4C$+T`wD`b9Ro%e@*=f|O$%YruPmtt z*i0Wt`*L2clcs(fXm=)OsqJj;XxCg$!czA$K#p!FP$U&+ksWpxBB*Saf z(xe^@pl0BepeU}?^(;oiDMw8!G8gi+OaswabL%K;U~ zp&pq|0ZvSjd((eNMgrK6WQXOs;Xlk7_RR=aI&swE&14>Llc`4(&C{{&(WVyU+jHtG zEJ(yTm`k!l1yXtDk}g4_zPfWmar^kn>bi&_dy+Y`{gu9(`K+Bo(U|s?BT`Z2yq0T2 z9ixc0?9U>ixvj6itpkD6T{jI5bd3&Bj5ECMsU_yQc1ra$>F3K6=5Rf;qpjofNHv)16X{n2X!=G3njJnL_-O*}Do*ufcs&VeWnG zf$cIYZyz}4x_gKF)#3>)^I)Ybb#RA1#Hod``FZKvwdXT!48(2}@>Zgv%To6ypH^56G8dNBdYz+!)AHe66^noS?i=PmU(uJgAo;+v=V*C3=qkLin!1y2m zVYP@k7md;l5kMJfgNjI_^dSYHr|?B>7d|`aQq_=8m;lIKuf6Tzm|{UFxgc0E!*eJTy2wA{yn5J%EIW7e$b6 zivR+a%V_l#LGhU^{pcEQqgA#>d9ROW@#WYsc`P0A0b#BE)4~bpf=pa+9xY<+yFY{Q zXOS2`J2al}%N3@u1>V~CkgZaLiV9f!-rdMwNrlu;Wf!J09ay3m*^jJZ-IiB*tp|dv z!($hiS>94{=P%&BfG${P?2Gkk82EA9(YGkp%YhJ@TrP}DSvn*7ZM@3X)bt6l1OJnx zO_mlMvwc|X&Sr%X+W<3+o!nSU#`U%i3tZz9!jK|2kx=vPN~>!F^j8qRBaDH^ZS}4u zG#345+c zOI{dPQQ}8PYPlUBnf&UnLHSbEOdYClJ#Js&MKj6C!Mw9}01{wMm! zl~Oa#CLk_TLP||SD@&;v?=v9Qg$92S{+5_H*HQfkImBp58EW;`K5S4z$Js_`b26d$G!x52|cwaog$4xn-u*H(y!BLS5J*>rbVZ3T07+5M`0<}Q+p8BVm-Cb z!s_a&RkZ)3EbM>bZ!L+c#pSh@@am~mbl!kxU!9|;R?$VLBI;~CwTf=aQz>Cul*9W@ z#j)>#VTmXeDW%gylIy8e9H#=gN$IIooS>q(UFxY-^eMAXPpzU~nFnk=wTb~sr>u~a zQwzP8TFBN`3%!o2%(T_0SCY0QmaVN;x$EChDQq3VAX`PP@@j%yzGFQ`)+japK9W!q zm7DPoSgy8O6-e_C2wp!&dT^Jx~ZMDh_-Tq*jD%Mu398qWO*H)_>we4C% zEl*znFj=ihR;BbZKC4kn4d(tXK0Do%*m99w5#N#Oj_uU0g$TXltpDU zrz*&lP~X_a!ij%Cs*YY@4v27_8kv-872$ds0hJOvD8fm3#mLkl5l&Gyj8M8reu1Cz zqH|Q;!s)leR7rNJ>J~mtKPy9cqS~r%;aj97K^CRz7M_xpE%ekarRo-?yUs0O$fHrC zb2&Hb!687(Cgt3$4^fvo0%%z&=VmpiTaVLSQmoBdZ+rwd3iSR~U2z$IRs1tZR(#Vi0JA zgxjn(kMV+%bF;erRwd_VohY(PIX7!a+LKz&EpnJH@KSPa<}VV@pg&8=xtagQ;9xm7 z^OuTJB5oSXR{j6-jU<>lPW-!l4T$hn!nV|*p%EJUP7e@LS`D0!CkrpCd0e3MwXXLo@1!OUSvIF+b6JhVm17vzC#3a&Bh42vaq2 zRUym-XZYmY%sK{^kaIKZ8K+pz%}fTuUO6{2#Ym;)+{`qi`Q_Zq1_r7@<;uC4jYSwn zBA0VB*A_8cIX81%5$2b3GuJap2{|`&1LMds7RZ=tW87RK|- zxtSZipkL0-+{AE41w)Vh%>gJb5BTRia&G39vOFa=wqKZA%hHtC7--wd(rk${2=i_) z%Tq@MZAV#}Ix1*8%hK$lLI8MIS)Mv7XuHeO)KNj(Q1-Pd<4ZffDmb zAkWnVad}siw~$YWkvn(pdO*#bA_Ri(LZ(GK_O(pRd#jsNvc^=u>(MJQbJ6D%i&doeomQ0Thr6(rLQ)QWWB?^#p zGf$Vz6d>njo(axD6>;R;%$rJcJaTU43j&F_ar))l%$pfASkBFSA)^G!xtT9wi~u<| zGt2N|IXCkb2A7a?GshUmnaJ8N^i{g?Ext5u)maSu26faMq7uXEie}liP!9)03Z?7G^@$Xm=!o zFX?h}LB_0;roC7P2s&@E-P|fG8M|C+9sXGsNQa@a}=+koZpx+l$P)GqIw;_jvvFq`2-r)IAj z3aTT%nWw%n>zg(-le_&z_(HBKh=^A}*?S>>?~3ZzZAR8~IdwkgEB#e<74j-8$JI)H ztLi1&r{uS~omO6ol>Ep$9>3>V)TEq}U((e<2vG7{v*Tf852CnV^{m;cDD;Jxt2K9u z&M8SzEb2RD7kE^jtPF4QDEZaQ8X9pvXNne>Q7idHM^%%_Qn->|^i6(1e`XT>2E*(F zK(J{~h#yue`9&XMHbj5fWI0x&`AW@4IKN-XFZu+-9lgHju_`x{Y7Q5w7g1w(Yqq0QMBFF)f$%PRb0ZO zjN(Tji*?&7T>@agl3(<#t35dGZ?2MG^k-g-DfvZDuF={2N`BFGH5%kfe$jVwz^mjJ z{ajRMqFAh)R`QF^#x#bLaOC=;iCS&gVoT6G zQ|lx0l3;+X649nTO35!e$<4VSCBNv`8O5XI7u}s=)d*1Xi@wE2C{pr^{+=;h zCBNu&S{Ljp`9;6yv)W32(c=x8jj#B;N`BGJYc*;=&glzw>IzaDj6TG0uH+XDuhSXr zI~MK<_U97O;|z6T4Odk1i$>N{nMoNgDz$84Yih9WoAfLB#cHJ4=`BaeFBbKfrIKGP zrfpowFIKDV=x}+Zi&$J6rNs$xk0lu3D*46gv{ha>kVSPqv5D1dj4S!Yl0o)X>{%LQ zKPX~pX}9CE-G_sSH8jhX2~hHjH8Kd#6L|?BhQ>XawGvm?7Ag6~*6Cy04Y6KZD3;k# z@{4Wo+HFmbSd-W6^tgyMYXCvbZVg&IW=F{{wo#jvl3#3-&ti|S*k);0t-_W3Vq4g` zdzAcQTYZRD@{4WrKwc%k*!Cb$X#m7_craJVFSgTTm%-*x@{8^An5khMCBN8i2GLhi zOvx{{rwAjdsn}j+#+-*K`Nj4zaV zc4SsJ`q&|6Mdy2!{9=b0%AO(mF%Ub#7+lFOb_D~tl3(no7r=0qQT$RgEOwxQu2%Sc{!ee;w`Peh*_-U7aQ=B+)nfsHRxqI9qJ_w zc}YP^ez6-l2iK`nf_*<5<}h6z4z8}B42O%9{9+><_9^+rMmflo{9-2=P^{z^JH_Du zCBN8dMkrG9i=7ETxsqS(rT~Jxy}m#KaxUU3`NeLQ6BPFi)~DoGyWRWt>QnNol`pqU z$&X%`YemJKt^Zfa@Bb?K{r^D8FY&0HfP0nv5?3|pnLf=~oGEVNc(Vq4N`8rd@?n@H zC_y8oq|VW?aH~s!Nom6nIIPR{=F{X&jobvJ{RRmeu-cD>|TAc^Z}jAtK^sXrh-Z; z`6XW1+DZ|<<&^vqSBPt}y#^N0I0`s*5E*h*t7T{DMKnN`8quucVyP1zn`%SNB0(Dqe$?l3(3f=4^JX zt)gxR^BX&6#~oAmEd~}T`PE&+9Lbc`Rr0I5*N12&zq%CjAS074J6HFNZT2elxm)hk zJ!8^br=*f!-Lp1MZh908AqbM)tJ}<+!Z1rEzq+@1jb0_cy2qH$7+L&Ees$-W*I487 zGIGym9rFuoj+*t>Jsk)-4e=E78SAW4i=gf<<`bsYmP&qg?`7^_rsP-mn?O6dd?)kv zYGpoA_YI%jR`RQR0rLQBzOCd}_bfx{G2|%u)t#4KU^PVT5synlDf!j+tKo|?EU)C3 zd`iu6OA+05n&dCk0HFb(RrlnoM)GPl9K9G6q0X{33JsD>Uh*L}P&^Q_eUc3mSIIB= z2pb&K7><%(^3|-?)L($IN}g<;1gL^@jI;bZ6m1HGC#UJ8dvg5 zjxm3@mg7r)pPAL!GVrC$2VSJ)muzN^ZaSXh=uR&C0B7kd`6L6Fl3(%_%)c!UPfC8t zX6|feN`A?gNC4k`t*qpi`WHEp%23_0l=@dmAa-5mvNT@=HCS?4_0bQrA|?oXWk-mHbjSSCdy@1tq`KEs7=Q zbUr1&)D$nq~vhmycs>R>@j9$Fm0oQ}RpItzvD#MDtR|g8^vXJmf{( zk+ylYrzqQw3@`TrY~23Dizp?(RIOax2~hG&?OnrKxmd|B{W5iR+KVE7CBO7-ewZu5 zrEmA6K2^B%ANUDUI}6u_l9)-q+>g@>qlW*`4>N_h^egGuC>FVF+Lumab{Ue{ztJEjb%WP6c#d&e4 zO{MQ=K_XnQPoyWq&-DziB1EbQ_z{d7xI2{!A(Cph#cMrhK;k9QC^GNlHKF zh5br?>HTbC$d&xkZ)X50`K9-;X`x5SFZ}?U=`$t2^lt<0&g3k;oy{HXn#&1j`hEt; z(d{VtrQOaV)xPFwz&Q>;Mb#P~xOC`VbV`Ug3&8N2h{8aua7JcEz zrIKH|kxhex7`RGoCBO8e0aQoHFMU0W(QwM~DEXy(8np|-VYo_u>4ySQrsS6%P;ngU zk?9oRm#9lWBqIUJDEXxy<_!C0gxRD|6fgaVqIo*jJ({iLm;MS15-C}wJab8xAW>i4 zxuLjy+ykocAJV%^pJdK#f2HqcK5OStK}vqNg?MV?+@=M>lRnOQw6N)F8^V_fFm%g}7ACsgna1W(TTGBsd_FyHy z^aI;vR^C2AN`C2sJMC=6G{K zt>o8G$)1JI3WB5L*YH3oP$~H}bV|RObh2RH051tt=cxHrRFg-mkG>ukYo!Y*098tU zYvmIo0M<%=Yo!|^fFhOr)=D2z0P0opTPvS10W@35Z>{nj$u9MrgjdOLt$ZQ`6k{v- zt(A{~09-5isn4wgC|t>Jt-P@ZkQ^nywbE@7Kq#T)w^rWk69Gzo>;ClbAnaDhl>FAc zn*!QJ-8fV7TlXHa1u6Nhd+*zkzmf_``jq_EZ~2wiDwX{FR$Ix>Hp^RTkdog9H4OZ? z?dV$+8`MC^j^q8Gb~I>8lMc-K8=AJP8^p=XEly4sCPdTLU*gncl9s`mwtWUEt8N|} z29HmRrtOrB)XiYgiK|z$)CW#rbS#= zW$5e}wqH{G&Z{^u@0fd)8IwL}E7Pt|qG^(9pCoxDRo^L&}l-nlL!x}m}8iF>d=DSGWsnf2~A=yle&fK(i$-ke3rC90k{je4* z9X>`}EyY$@IXN>oh6_7ZIWt$7YMz)|CgJv&qog)_Hj6LHply3mgcfOR*HELiV6Gsm ziLvfcYYRPC3rN|dT3hHt)F8D^aZ;@<)F4}q8_$c-dSf10P3ye;OGj}DO06x_V%#mU zx5&TLIS#{7YYT0Yg*awctu3@$W_9egT3e{qpo2M9N3AV%g+WJf%uKBAZIy@VSgtf>Rr@`%0&mCP_yhQp zkoUzpuQX*<=g$DuJJOU@T{QMYy)8{y)lGRSC2UJmRvmj4GFYO9iu?`!PofVgJ8%R% ziK^pNAUCP+4y#U3QQR)2DXaRF*(Xg|)vwG0wlrnc0HsZ98i5C^vt6ewK$6naIg>6Yz{AmK>kh^kk)y~jpOXyY5slnzt&=M04Yt=YDBft(1nAj z`RNhyWM#~Jk6DdMMTQRa%wbPL^S$Qla1f+hRr-FJ#uujtRr&#$jzxwJsq~-8bUHG0 zSf$@5)6J2gBP#uVnZ~!J^bP98CHss&U{Xu$kMv*cSX>b12W9e5B$J!!!09|_CV?KM zWG9jzlF6$m*@fhXW%3$Ib|d)_nY@mY$B_J}Ox{4r43Zy{$@WN>ec*@Wkvb!t3(zon zSk|ov2}le5xl9Zp0mYw>%fx9U4hr)TnYaasBf|WIOiUwjg)sj@Cgvl@e%Au_x;FU&_};w?as__R#C3rJp=kIBUQPyiB- z%fv?`!$*br8TtD!BEwe-^Rx2zI3v;s)`>DkK zLSgRJWM}+G2|n%v-Ms%K;VH&k_S*gW|Wb4FQR}fQVXx>v^ zBi7lNJF<@^1#3^^e!+xeBL~Q;3`Y)$$Y*4-lfD_Jt znNWuR&-fKes*;+t%JMG;fo1;27)Q4C-$yYUmW63l(9t&BxI8wY4i~EU1l=U7 zy!p(^3OZVyEoEDscpRyEC1qP(r=Da=%C@?m#$Tnx4vOleoD#{@AyJ*8YEf~k`1P1*hftw-BLEN0$XRa2vyLzw5PzDRY8sPFb?s;H)xXjWWvw(7^o z8fzhbY%l)Ur7Oerjv*>)=&3O1q_cQvobK<(hVM`>ZNrx92U{^pV&?13k414T`zk+$ zT_}b5$MTjdB5I*Z+1?;+6_Js#DP_1zK6NVb+5aMaWIKUd*4@%n6_Jb7gY(j1VZKpj zG;QPLT-kX^m?V5+}m(6=5cePt4?tE{SrkV&f`=FisPh{?xwCT)m zk<2o#`NRMfdS;<0nDxt06;sN*_mBb?fX*>h}Mx|pijpx&MRk~TG@r?SOO7E9xdQN>`8E#MpRPG1LFr*Bq z-rp+2Ey{oj{+%++D+8+d_sVd)GN6(_RE9SgLXBj4Y{{W*h|M%mzbqeDTe@eKGGpg4 z&H0KPxG@;eamw_BGHv}bMs&a~K{Pv)Ci9<7nnlH`hM1)e76@UC4oD@k?$H4$ z{vlSI|I2&=WklNX;4HW^xu3~lgNa~a!nOTxX{(Hk7BB^$paCn)pG%uX@)iD)&8N(t zqF~cnz~7o#T;#uV>RKbJil(II536aiS~XOR{J45woC>1+d@?&UD8(!@(DwfK>I+xG%^O(@7h&5q8T|I{UsH#4ITY&kS>chxWNrlu(M>gq+DLq)+QJ@l-5fE|y zTils!7y@EG_}>^@Qp8!75G3L(0f^J7QvD*%`oQv_!6MF@6fEMbaVaBILd3Z=3mP=G zh_mLm}2&YFICBF>s$EaL3PWP6aJEf;b2lLAGYi%8`}oc&~C+nxh_Y<+0S;*3_Twp;;iYo^<)rUOnXvEo|H<&Ma)`3X)!tkF5;|< zDKFxzd2YSbRT(Jatl8y7oHb7lZ!KiIhE-ld0i&jmWBbANaiqe;kJQ{+L8<+ z&YBh=;;cb6sJMu;A9GGsj!4|s*RrBjZZ6_nl>1C(q^n=<=G8ll?f4+#tSO~MoHa+D zn@@bXiI>sW)ivb9n;BkS#91FFK*ZSt28cLo+|j<%V}CQNf`j532oP~DE=BX0h;uob zk{HHRY}@4=6*IK$WqC}*dF7*`w4G&3<08)Gien)aJ*J`#9bR|(MN zT~U%(Lc}@f@Kh``+&b_+n(4|i5z#9zqjX38_Nvlcw`hlZb!o0o#rB%gOt(~e7zp#) z(oFd-(b3b@aY8`Exnv9YMVwb4IwH62WCg$dALt; zN3*)KG%ZNPx#ZCUMVy1!mm%W3Vm95gdKSLyyD5= z7J*j}yv7KKIIqa|4gda?bGT=qE`x!Ub6k#y^NJNMDumrOhMq$mnBwt`D`$HyBF-zG zLdn9|sbroi#bIi&YB`0B|e>I5^>fHA6O*fteHU~&Kg}w#5s`Z6LHp@6-AsS)hp5LQC`j` z0~o;~&Mr|;;5F4;l;}~|;c7haaSFW*zJi&-He5DF4B#ym$?=ZHKUpx}J!QMjJ zQ_2wHKxI^dvHfoNdn2KD4XJW=X0wa-*E0x(n>&}!31c@c9!5g*c35LEg@R`1XL9np zS!0i4-)^&aWf3+xKew=yom!k6%g-!B3fh={JgpA*G)|QMGw%JPorr9eAB1$+hn*&W zc`}0YcPeu0+d-gb|$|#om)^+ z28vv9*A06n$CvOS?ZPEt%#!E7kB)-)Ug^*`3KYRnaaYgY@7uM!X_pY6+JPNMX$Nel zJ;mOqY=*3pFGKdjPIj^P6}I^fm`9XZ_n_E+rwzXe@ZPuBiFYFLQpvs1ti9tk zx8MH%i2d)du@3+fHPbk2YG8XsW-ax|0X7_HHQF5$txo9YcVz!j4^k`bak}adje?g` zvtqZ+CAub!!!+>G_&e~q0oorU{|GJMQbX^uTk?}AVgvq1Gl3}fAF=IUfNlTvcH&7& z9J3QYK%#ZTPW;r#+9Sll<5*>;|INbsgD=Cs^uPJ8^#^apzx2QPlJ$q`@h|G0ocP)Nz}Ujj>p{}RZ(%oF}gL(Uui zD+giZ0)6-@H6IcFOC}!v`&twu!+-bVWLfwxB|YK4M_{nj0Q`bMjUMxc|B@+f~u{uM06;lGc- zS{(lS1gvf}X{h}vS=g`fH&#J0uktdBd!tE1oyP$soM_Te7oCbo*wLh+Zpu?BVLO^M zbnG9%KKIvTs9#3#qfS)zDwZ3?Ry9Nb^0`rLRX5re9mQ5POqUBtI*P3- zLl+E80a0vKBdS6CQEXMCwp~Z7$tbp}lXM5Bx|fJzt2#xOFA@BEpjUl`#(w$uHi|Wq zd!U;KgAO! zv4g@&%1c6~4hbto*)Rm@D)>A6lvj}x{$-_K1yd#2Stz_W0^YRNAQ&Z8LwAJ@_$3RV z*5I3yM;@e4Bb7~tyGK4mZS8F5tu`l*G{~C=H=Y-f^~Nl+n%1KHOGj}DD%?HNV*Ihh z?va1#X5=uOaQDbIS%_nH!`&mhWmd;-hr35w4LX=(b;8{vR~U2z$IQarBi9(eM_*}# zLfRv39-|%T9_jX5RiJz1M3G$vx<`hjyF8NF3%bMo-NF*rD` zCHzZ8DT-?e|4ISy*9XM4g#VqDELTMX;#$JLW~6|)mhjUIm!6fNxR&s5%CPWSPH`>a z|6m-rzgCEA3ICSSFC(rc{5!_?#kGWgUxXD$7KEQEA{EEAgr6-Ym5gf%i#px&s!BYr zC2SPI0Wk>S3dSmmYYB%KdRcKT;mXU(;fretSFv0x#`b#c?g+Rg7IGt|h#h@#OG!*Y?9}{7}H?tMPN> z#YTQ8ifai+{cwr6mT=5Z^q!%NYYEpfk}s|$952FDP23f&aDp>@aV_CG29}6x3D+}D zaa>C{83=phTEZztDjnAnPBWT6t|i>SKsBh`xR!8Z5e8=)-<&+Wwus@zwS?CdVfMlG zXkE`JCE{Ab8yH898E@Q5xQXEbo0Er|8D1u?CEUVz{XiE9b(C`(gEMQJNr5LxDVXmD>lWxR&tYK%Tp%;l!(ij|B2)$w9?8*vs(YD@yW$ z;#$H-OVjoGxW4sXS(@%Hz&ka$sx;Rv+TmVZn(LM;*F?hClxDi6D(1DNnMAMyJ;K+O zrg`F8!q=}vlyNQL8v<$a8K!#QiE9bBm1g1&CF5Gc?WH-Y-`#=PQJTq5x3e^@D6S>k zRhnEJ*AngyWCur@=(YOrv6Zvwp4CIKXXR|}&~b)Y@5*`HLpgblubc;cU`MKiPh1Au zjcW<_t;}}MK@IBum2pOm9v!$ zMJYOk;r~Qo>{K$(qZoEdBhMo{JNjr~b|+LtUTV}L!@ZsO-t=TyGCex%&B?>3$})rF zTEeHxW(tUF37-kh!Q)!OH5pp(-^`f7aV_B&GD=`vOZY{M5fIlB z&N93>t|fd6gG`;Z(K__$0+g<<_ldB z;Yr5uf!?^5@DyVf#kGW|8Co{3C7cgt^0=1pt&CGXt|fdh=D zST2&iIFlU{#%}89NND>hzg?cPqh23S_M?t{7RqiHHj-OLdrURK19WF8QBv zZ(<`v0VbCVXtr7E24h$>>*~>3nK1gOdd3u(EwVO!RGSuAlRm0Ri>yT-)nenkDr?|z zl(lhwQ5b_2IIh@4$N9NkyG8ftRL{+O0WG2So3F%=@6eA<{5XnejxB@uvE^p`*-H7F z?b>g(^9v{U+rX8%zeztR_pk9|o1ee^9YFRY#%KGx@naf4&}66VLS>WfXhXH>f1^Qs z3-zuP@5Kl7|8flvjQSRm9Jkt_;?l3Ib)B(*q`KL?$~FUo@!1wv6xN(Vw^ zP;$vYC<03cLJ`OVp@tDD5gZ6bOiv)xX;3|ZP%nbP69_c{gC`J*3;}^qZ-6;C5ULfO zfyf*DeJ+7ee*``cgrZAOL|7n{?Bl>dsD5Pi215Oe3iAX)(U9{7Ldiks4TK^S4}^LT zijjd($Iy-}5Q>tXK&XBgEHwbXV91X3213d1M59osscG%RVN8oghyR{fLjyAUGW?53Lxk*?h(7RPG9Hc3&n;qyKGMfUFs29{A?pqC0;Fh|^$N1~ z$VyIPTArQAPvw^uMd&Cs_E6koyOL}-#^WkKj+8ya(2Lqtq%pp8*tiqSPw8Xo!ip9i>*; zO?fIMY)7e89(yw~SRzVAMlgS?hoCUiJghuU1#**$QmZ^cMRB`~QmgD!W?z(AWxp~z zQEHU~lulVnL9Obw)IxS(TGi{Q%5GqqY0=f<2sYcHXy&eup{AxqH#!HhL($Bu337~1 zD4KbUtWj$G|0U0{@*fn-4Mj7D2p}zGM^MeY(YEMNG;^44SRm<8G&4iDESLg9(aaHb z*8Wg5bJVu$kTV&IW}c*HAl1D@D4KbSZlFZ)hoYHZp}WszhN6WJ$a{_oMY9ZJ0cWms z)2t@r1*n1(muB4~vDMi=xZ<+-CTsYNh*=XA0|=OpbkF1q=Y*A$DTorOqICP&jrS~h zH0lB#|5p9rIzY-M=rzjH&py>IV7D;KuW!dcE=Akkz#QK>nqpxC9mdR^4K} zLt^idf9VTR+R$Lz+xRqvKr9lIU>R^4jQ!5pg-|5km4K}T@REdH(f8sp6v zAR3|gx9T>J(T;zs?)F<%{9E;jBD;)#s~(c}q>g`Eb(k*qQt@xrFA`ryH}Q80^rUHh<~&Gos}%3Cj#Q%tY0${t(8OGj&X(cG{dC_HYonh`b`-Y z+;)B#b$@n)*)ajltj(@X^A~+yc$*N$iqWCu}#L&x%f3qqtD~B)s&8lL#R*ZkM%p$gX zX6Si;{F@bK^x*h6%VHF@jO`TUMif~Q#wip3W>qtuTQ4~vvc>Ul)+)v>6aQwdW;{8( z-4GCKjUNgaeKmfLyx3?7mEzy5s2?s7|7OMfMDH2O_&2MTk$mxQR=fyPHE~zItpsQI z;@_+~29}6_v+5bAIR4E_2EyL>H!He1(szK$(zgdk%m@od#T3f_$ z?+H1;@_;@Wob_Qo3*Db%|0r=ve;Xe=fuBR`^wUs_%~}mqm_$)vkn9j5mVra zf3sT4)0{9P>);AJJO0f&6v$IoxqWbof3pq;^5~Z5iEFct1oGTPR3}c(x}qd6DE`el zTAJ=gkm&de>&nt}H&Dk89I~z|&2@`*xL23vy5-7n9_yOYOt)0UytXux2zLCNbzNzi zC;rX4ekG!ef3t1~q{(NP>U}5v&1x&n#2re;zgg|2Io|j;tD`iNpKfPqT2cI))m55Y z9RFr@2eMa+f3uFQoK5$vo(1%*oXs6N&M@m;IgfiNC(rSf^XT|D>%?WS-S{`FZ)LW7 z4r);Mubjg@1C?W7ji;C z+&KO5Z`RF>865v+y^v7?+03 zjDNGn8KXq}n>7)@@y5SdIYyC>Fkgt9uqGM92YTb*tSQDUihr}F8Co{}&B_NedHkDo zE8~=pf3wahsyDig2d!E8q;#Wr83FNc)~%YTCvcvk&S{1_b>rb}){G{&MR*9aUP4j) zn^h=HaN^&rIn5~%|7Oi=3e_|q{>^%^rj&_)vlb*RF#gT@v$ZFh;cMQBKc;mf{w5~z zr|#zn#;Us=4pjMzbp1#A5Xc0rWQ5LTGYEj|9UOr0X#40fvEN$N^r9B{)<-VQ=Y+Mo zNyWT%V7(miKoqz(g2k_#if*&kNVp=>fjuAdhG(-`&&fT)mK$gyHgR67K`(WXiTwZYUf)(@>(32cU=e{5W=17Tc|@va%7m!A~!35^8O0sz4YHZOAfy z&aUJ3rf1NM7BAtb*o3^4_rbWG46+{%)9@%>#fA5ObuiK5RmlgT9 zrmjL>p_do=x29gQL&HNI+1~DK556kw>k>8Xw4&3nG&a?NZ5Mh++M#HReND-;UUyG; z6LvAx_H6%X-$*Y#mfJeJI??RO-c$JkjlV_Gsmh+;pFNNr&*mo=v30D7?)V=#ksu19 z3~kCzMd|I#_Kp_L73MA!MC=ruliW?YZShiJTmz5Fla;&OcFc?|E_Ng2at?Y|u~|bS z{bLJ@(_=HDw!n-7bFO(*HJL1>Z3-LS4xYUg*Mg{hlOGt)P3CAdJ11(t!7#g|R#Cer z#1A`zAQe&j5VK)3Xqzm@YHhw!^Sdr0TC^}WgA1u(Uy8L)FuZ?xW+{JTFSezqaxqW0Y! zwQc>D&M`bcju=>+%1rz6B$`ds-W4g0qV2A(*04OU;u0QZ6hC@U)ZVsAmjF0(sjxJ5 zaUeG}hk9en+}gLU_Tad`UA*K}?q^;sv$TBHfljW`*@iOq5OctFH5# zm_zIXPPZlQ&mqUeBpw0Sju87(*51JwXsz+-g}DOanMG|}t*yvQf&o2<1EGAc4TihU z<19t(kAqQqKw$S_8VUC6zQ6eXWdtRP+K;Gdh`Oq=Ia_X~KZk%2xxqUcVne+?Ejdp5 z#|qfV7RBDl5DL|H?gq7%dOXV#(WX5zKu*+7ax=DW!VSy5I#uuDU|(mHQ)Brhd8t7J zP}J^Dv1(vjM0&JhJM1Ys%>@L&)V{?>fVSbxvU>Q~jNdcH5cbw?zeL?Ooz?}DwGTUr zA_U%N?NnQg)*f%r?2frv^$bHb)cs}iT8-L|^Iil8xOIGp;oaB_Z+N+YU9k(IHoQ(} zwA%!QI@kVjhEhXQ-1MpZ()7UGa1KL&cGSBxGS@agKZA({O$p$j5w(%^RHoXEePFb& zPsG=Jp9~#sBe>i5w+&}{unIXW;x*Fj^p<^9iFnjwrYls$W7;wax3tYtOwAHzp_T&0EhoKg)*I4JIvxC+F5l;r$TSYt-WIrh4X=#_S1zG)Y z5b=h8l`YekLCdsFq2Zn9hKM&Z2zGf1AR5O#nY9vE*OqLfb^6$LL#)>pdJ-JV;i}A! zi}(hwy=QKQHu#D+dCg9bi+HmJ24`^XsOvD^;xP|l$51>`MSP<+%juekZ}M5}@fF`J z?W$FVGN_*YM2>G^=RTC_P`6ctGK=_DAA-q%lWCg=>Mab-;0{RfOW1rXzC8$3I-2nv z9;|a=Y^rl%ZeGN9dhG4^KB8mkqKNPEn5kiN3pDXw6!F~*!WSx-Z{wCWHi@~0i0>)F zI`bIWdzBge-_bd_cyewA#fkVnM(*qw>~9;VDY|n#$M-YX`;dqqU=W6lLVXW}cq=2} zZbGLOE!9#q3ju=9|Q3tj6vVtxTkRi13Ef7yRm=l ziG{+9h#&O=7|u}HT)HGh>f%>=LCV#M3CkSnf0Y-)smJ|oCL1(0)1m=bEx(8UaNX;I|skP3(||0EUL|G&y3@tf{%}I zIktO|V-$)hvvl|Xx~#`$yp7Zuz{%4Mk~L(Pm(z_WnwQY+C3MWq%q@5s$Gi;L5MD-) zm*KRbm(=Se*&X2J9QSf~>w1YNyhOXDy_`NT$1_m8%>E*#95i0ifS2TUqL(%3WjP({ zB@KB=r`6rf%ej$raGg4+eLoxKFkK!FuCAX9hmS4f-Rue;;qa-<@wNrr#%7d2WPFr^ z8EE0=W>v0}4CtMpSBRxcqlH=fl`MXW!v)l5yn7+%%);o|bD9x`^5aVoR?g~s=a~Ss zt1ztzHw6&n?ezr`kQ)HPODY$TMEqtsL2=(;eQ&Rc?cTRn1-oyq3Hfrn_9V6>9T@Gm zUzii3;_gFuV?K%a$Nr&_GwP?D{a_#Ck!)|PsF4325+V9`_>icS{~i@p^l!%*VbZ^y zZM1DL{c49-S6I@9_?@oqtA1e4qJA6_2}wCB>XhNAsFwy5n^YG3O3^R5k#3rP(b^Oo1EPTv zL#S{g{m8U+ceM=syU7gv%_T%uWiB5;1 zOwjIOUMjK3wlQ%87)k$+J;PpOoLO!kb13)e@pv z63+~Gbt8tIexn(?hEI}X<#tN;_VslgL#I9aEKBvbWln&hN=4XW7a5QgX*mb%$NYS5 zJTreu)ITaG;L7aGTI#QA(ldRUvp7@S`s2+SzpN8Ow@mz0U6A?@JcA^ zPjA(1yB_#V7eL$gBEZe`6vM~|NUvp!qW)t$bQU^t_uz0puF8=PQUCZ(FGQ8X72782 zXLf01cy4aVJ&3hi18o!M^NYC*#Y5LWtnJFV!@QMHqzdn6H=jz8K6Ag;CgHuV=e^Ws+06Lpl#$;;Y61{LP%*wYtQUAi$XYl@# zR)kIrzW`2_b4IcCa%XN5?g8hilczQx zE7alu+*p&iitjk6v-OQ#np@U`>SqjU$5l`M2r5<7-+f4DqP-*93KLY`c+Qz~*Z-O^ z2IncWJ5~n{>&%^bd=j&C3cjk`f-3sk3>{sV!R0IJ`;X`xm}unatDV9GTqK1>as}3Z zis2*E%d=+-*fRkRQ2Jz^nkIII&fkf#bE&5nORv2Jcu?q#wEk5Lr%3~vM^)x03~*gx z)jq;OzkJE_rYK1%ukK{;)*bJY=Sqm!v{wexatHGpJ7%X3lHXz=c6VRQVaU(Vj9nTS!@FPd8sXXlyG}lS@dU1EIlYG|3$xV-9;qym3 ziR5PH6o$EvZfVK4d5yi88?w4T#(c)eV!xh`(j-h4d7gQVHLhOYowHfT{KA@}X1&R$ z13@S2Q_N?qvu4Prki3iegsH~)!ZNJyW$xgU`P>Dkq~8SE(d9dtx0f6UnYm?>14w?u zXCE0`n8KFw$rmsWu;$yBfAU#|(qjlcgb7ExNS>EoU^PVT5sypbJnmr&BGs>kFV3)S zd1+4FrtOYDz&k$ul$zs~BDy0W{R=ffXaLA1y&M%My^iUt*>Ln?ts;Gvtx;&O4=#`N zLu{aUAY}U_8zyvBj4h2%i}WLGa8P47^WF5TS*KIQ@FF)a(uY}R>*{_lz=|UdF$X@8 zWfi}}THiK;dM)##%cEi8V=5>8Ad4bB#{A)3@Xjx&R{B0OtFvX`OPLQmvpi2b%P_Q= zIlAe1j-xxh>;r7qtw=w~0JU?Ds>Cape_I})5AKq5Gj}%Iu7UP3056dMz98$zl6*G5 zG?|@Uyf{0P-H-o#w~&T^kt3-L)g4O>|0=0{z3muH{h8DKeWKxaNWQ*!g3hToUuh=$3EpmOE5vBt@7t1SBPkMpvX=h z3!JNH*kby#*bhp~33>~Q^22yq?r*rSh}c1MS0@~xArmE448-J)1>PKP7(EG^9s)AA_ZaT=z0*#wS^47uP} zy%{?*gU*w`;ak3Z99y$W*2+1aJt*LGo3WRP8|qfEw!qb54|vgVJQ!#d4G(z{ccg7z z?J3H(Bg4zR02{YI@gjEr)XK#jyDh0B+)C|T!&*7h4u#gGiP7Oc=e@7-W$Nm*7e#eFL7ESr zb6&L@U+IT4bCXMWm@Q%ED;i(rM>{6ScWa;ZtBX*Icc2TI7CO~?S>tQ`B(-jpbC;f- zC7Q-NN-=MmE4T|ejdv=R9C>P~)n5Nl}9!y!+1`ZPqffW=+d1g%z7I9ZkbthaPZ4xex})Nq46%I_?xirqUI=U> zDmpJ3Ti6tfO48N8&4q&-Dzv*C%#x^#g^FXbl@iV2cgQD?jHs!-RLT@3rM7?f%k{TcL!gz(i z`zM_e+F`U;H11~;L)zcSzJf&K+ZiyrkQa@6*t8G^{mRn#0GsIpXtv#ceHCRCt;2EGeC}RCm5tL<VPEJRS*E(L@1dJm_-qG)`&m>^$Hd-4T>Z(_4n zyKoJo7e1$OT7sqq?17q&Xgthjt=f7$vpV-2(P&5L%Q5d*DUYiDgKUcHM``SAWm8rM zcZNB+(nRB9Wf-E7Pi_7Asr*wc`ofP(UtD7&n+69laFvXolaVxyj|NaP@Ji4OtMPgk zqv4dJrWKhBd3uj&>}k|41cx!Ske`zwL5&XuqUy<@+Hyd}ai~Y8Q-Bjwu>Am z!2-oiaP5x{P-r~7?u|>#bM2JsY0}S^C(zmTZ7x1LR)##Y7b^F*Jt^YzhI_Z_8JlN9 z@dR^zci{B{E8%pfR3ql%HhoNbH*uyAKV|l=!uTBBHx=gI#~#=&v-0+VbFRC0xL+-v z&@vBJx*8Ae(1$p+Fg8CgeY^I2rj3Eea!c}7qN2+h?`II%oyXKL9IfPh6pd?k>XPYs zNHGA8w{q<#nB&a_F$J>M1lCrvXQ8u#fKRxv-gHc?eV`QBC07~Nc1pjQbh2RH056GH zr$T{bYtYva10#qLZ|msF(wFCAy>ua|m?sa~(K$TWFV@Q^MgWZOSP)i=RV1-qx*-B6 zBW*)nV!iYs1)!%8BHo2v$h%ZE(MN-%;^N^dtXhzY5$R7VG5`A)uJ< zzQLiPGh)4b3y}&EkW@Ve(jFVeQ6Id{!!~4S)KRLDIgu;5=HyhIdmyyNHjU9U9N~ z#5c}vBe zzkv4wx?r8LFPhab@Z+|lZ&5U>fk1l{&ypXcB~2PK>u+e;viU}w%-rH6HvSbYTO+W_ zB<=*FWg96?S@C&<8R9Y2vYnEVI641GLue9_`=VtB6|`C!Ma#}!xP@aI5U07M4zr80 z7-8e+hUG#Yw+j@yTbc~g=91;Mik3Z8i7Q2vkVE(>b#M$3%0p@lG5alh?-_!=Qa=#- zzaC-o8T@Nn#C7$G&W>TxM)5n_IWX^-dzBfJKFr8ytw^*?Dy<~QGO7AbskAMDbb(G2 zLO7!3R+7na59ONYNMEOE6smzL0KVnU=3%ViXR|n4cL8BSTHG|vxD8NT1H@}9L^BoA z^4cGu;x$wTj#Yq{goMjTLw6afV3?Gn`Ch*(5T#BLEq{CtplQ7re_M136Eicj2(85y z)MJa7aJ1Z&N36bv&ySDKU?$O}xO)JEjqGuFKv~vrFVCGMXq;B=n>$SGy^TNO}wyr8kFZh0#FY9T;aI zq`4Uz=h|tpg>>RPyae%HNi?!gNUpSrtp{LzgRNtUHjw`r_ipQl84|SO-*2X?_;+y( zdgIu@XmiJvS2ka<_t4(`&3k5#9KxTa!^j~6qLgX%j4PeW7!#6WUom7Bj6BJP0!-3 z1S=LU@+|C?_BO^3xRYXM72T zgsrdPueIc8f%^46L!UAx(NvKQ&1j8Bjdy}9q!=d#%shn#gg$N1PNbE}I5UGwFFOu> z!^foAA~T%$6zv{*-1zTct|n7{LWDkJ{5_JJWk%$hqVG*Ye`Wj(#vbf1YwLZ6z9mzt`IHmcu^k`s87IzRS&}U| zlBG!Uk%XYgmTW80wK|-bJpwFO!m$t*NFapll7uTjNFcB*fdGN!2oRERgfq*v%PtFq zn+3xE{l2Q|s_O0;IsE?5vwkdT>U-a+uCA)CuBra|{X7|m7Bj@`7_Q3W$MAF%&GR|$ zb`+A;D4u6n;O804Yj7O;i6-YG3^poIlzhP}g=+E|Z^1FT^fp_}FEX=PBckL>-U3i} zdJB{|Udf|g6%4z{fLR4i@?|dvLkAh=*zgz|dg*9`wCT#ikD}ypuN6G#ed<2b!ki`V z@ctH^5v2bfzbj;)DNOD|i-ourR2O0zoSwrXFI#et_f_!A0r8|?@^0@w?#8g#_i!IW zEKV!r&8oa5@AYm$)`fV5sS9s5wTZHl`@Qqgw&h0ev*i6A4LO+jWiIN(53nUg78Uro zQ(3-kANB12kasmPDur(Wb-T}dj?Hpy4={7b1Q z+pcsar8%Z6Da{9PrR~LP+CM<)d^)w~a=6=-zMRfK#V;b3zJdlzs!b+dN!9m#|M=MC z5a!%oNq_ZGXbJ}DbMQOWrEISu8&d2VS9>X3!<6p-`EU zAZ;|tlw{3P_k9l^>P6|-B+F8!Bmns=WlCkSl_}}c0?AgUqzM$J6a2D~9M`l&nVS)1 z1G3%pb%*&K&pU@j*+FGjOCNpdmK~zmn(8jsOu8_-(D~XfJ4}~45#q{}G$-Q5MT?J- z;YPZZ;1*IUZy|JtNO9O>_A(4M)76pc@4N!hB}DMrC$LT^3w0`~@yjTnvVczI-5{2! z7apNgN!Y@uPUU5IxwAafsic%B4|OUjnMQXn!{0Jjr;<#yp-$!dkgB7v*qcSBR*rj0 zkxnJw^BCI-ok~iTaf);*DI3N=4Z)A&BVW>iNYPg`k;z{JQz_X~_(lMoO8Qv(7^QiK z06LXy`5sxcP9VR}9q;LJr>3gd$M9hM6dW%-YB@yZORsRwr8tR$k(#ell2^Q)5*q*lR^lg^5O49dN zUxGtt%lk%7(0f?)c3=Aa)jvcr`Eu-E;tNOm159Zw5A!_0hNg0UzMK9ar`CwFf|X5w zsQOj-%CMNX4@dzbxEAgA2UuFm!Yt(TkFl91gj%z|owlHD{M+Ll42xZ<*# zhJI$Un}#2k-Hc+~9T%xKz7rxl4LgxdZx0QXObf>yJ>QriR@;S9iAC_K0$WV&TO-gn%QhH(8 z%?QywLoK^$NO9TCC?;!S1h;Ces>0WsV=;#nt+l|yvYX}*iL#qXa7=d7kV44_*@**v zEeHDL_Az8P4J|=-(|~eN*|M8aOrI*bx3^}D~ZCA(RSX31_E+B~wGNknL-L}fRN(k$7{;yfd}nZ%RVsXDll z-Av-ql*iY3D5tr@>I`$fp>|WqJFg%wTo?>mI&M1)(~W$enR?GJOb_(|wO-)`g}GtT zn!BqoH!N4G2wqs28I~%U7Zqj_!N_hVbpSQ&U{rQ<9-@}rOrr5UO!mGdyIGKlnMccR z7UanB5f04O#M2G$;`(&k3e%EgHwzveW3ant0AKXY;Mkj3^cl!*CLP4dW_s2ft>al7 zO%Joq`SXN_(s}mJpU08iocCn9ZQ0Fv*^%MjJ%4S&Gmw|Tf%$WsiR|XQ6^#{Qjf~!B zQ3p$-^0N7}Jsa80c~7BWVb-bi{{?ljPHEsT$Zj3|U}E-yvYSa~tjRpX@f;!`yIG7` zP}C=X6K8_#rePM8-87U!vYUpHEW2s&MA=OP7na>L9KBRU zFD1%u8fGEcO~WWGyBX)uDt)k*UVMi03gQD<1A}iR5oJx1-86+nz?kf&VJ69L8gxF{ z%|vEIcGGa?mEB~jE2`;eWscS-Fp_0AL!w#0IYnKYP?V#pIc5l95e{M8B_zpiI+d^q zmh5K8DJ;7gQfQ_~mfZ{~#bq~%mZb+X6^-Fm`Vv3=M1Bv_OM6eAo*@OyaG&)ndD=8x zdT11W8Bo0AP1CQk4STjSezR8Iq*(@s(|-IUT@+qfS4`=4^Q{oL%td(7>dQVx9g5BefPnP6WIW428{aGMYCi zUcVf{L*%1)0biuQ#pu#kcTx1g- zu_U%h`lnVg=Pkl=EA0Ny4QBrvS%#2cEa6h>Jx>?UvaP!+Ul1p!TX@}q=HDY+)OHd?rpYP7!G5iTXu#scTf z!lhK%a!0td9u`sF1y3I(FuG=ihkB>6dmj}pC3{7ARJe2zpCuLG2$zx>+x@n1DLoo% zMBh-em(3$wdI72xq@RbrEGr~jO2wqYT_|;NK)7@_vMw$rMjDEe)Ta1aF2?QdZ0+mm z@7X&bAY4l9R8+W>9^);G3YXHOmfF`XX+r4gBEqG)Q1&HJxb#ankt9m^5@Y2$Nud{F zwX|mTFx4_gPJ2?8Ap{=elVxwdsBo!4^xK;dE;U9+xYU>E>-73=sgw`sx^>sX*5SC-3X7{ z!li~`Y0HstX(G@eUAZ7!ng~n9ItZ60qUOyX2$v=@Lg7+_wk8Re8d$zfXM{@)LLR@` z)gHp720)v3gu235E7PWX=K_hqZ@v+#&;smZ8jEEI~Ffklh=FEyxktv(asQp%O%$JN?B;ucJ(?+cyoYo>Cd=j5`{}G2=^1d1mNx!p3D-)x%FflEj7nh z4YABv=+zA)T)a#4 zr4hsyE_I-&aA^{#g#Ok#m?d25*!kTW7A|$n)UZal)Pl%e#1SryVN$qMnz80_gi9@Q zl5nX7yElpI%@%}VBhknWp?Zr&!fZmPMoWR}t(F~`l{D!#%ZkpA3YS`_b#pPdf$AL= zgQieDEmfaq0j_YV3t%|&OG{EC@q8B~WyVmr)P+dh0k<-(9l9%qYT;5BFv6v-U5jpt z>Wf`K3zxc9TUt|8?{+~WT)e0r34F?(g#bp zl#*Jwls?mTbtqg)1|?i7KT6?J`mBXZ>9dw9T}25aTuLb;TuLb^TuPs`aH;&Pgi8%z zR7%@4!uM{q&k8$DBM#^akmr^+!Ue_;ZoP` z$T32=)SxlpQih5NmwMzLK96vz#VIIUYHFH4tvn5#dsU#e_=@6csKtNFm`;!-xr&8YoG))SyPV)Yy`ROAVeZ zTx#%S;ZlR6ee`1rQTN013=nRGS;D0TrF{@bxYR(2!leZB7IcDesmY43!J%+z+{(hG zakKv31L0BwCJC1sl#XKym%4}}TpWl8R8nvDEMrrnTEVTDUZZMTASEc=)iN-c=;w(kQ_afP8%n4CN#% zOQZR;aB0*|I~I5hPr{{9NZly;;lPY7TpA@tg-fHjZcu))4Z@{S+!ij4VsIUx_8ru7`&lyX#{ozFrV*5(5MLJ3!(&;3N*#PFpAR`Mg#wS6t)F1 zUlavh-OCq8VMk}|B~jE-#(ZfEO;E>tS(GH7TO|sYMw&@8Ex|PC#mVw`T**hRM!3|@ z9~CaOFt_hsXIIeax7XW9w9npPgOUEa#m3yey48m4etM$~V4oDSxu%ETWP@%8-eyBi z_q^Fb61wJgNia>RH((aO#X{5`h28>L+-rRyP)1agg-gvHno2U&zrk93>E|~PE_Lbj z49XQQEryf0-d$yeVat<}aA`6^xgNDJ>NiKY)MRrY7A`G-v2dxul-wruy4p#CaH#_) z2$ve1^hqq?QUfUAQpaGvZb7)zK`i0YB)eXmLAcbws^+`^g>b0>cywFBr3O)1h#<3_ zw%k4}&=xL@kUwA|qTHr&_|LaWE=e8fVzTrAeqOT*?f2 zv(=3iQ{=plJpt76Mzfp=|9+dHCL^pSiQ@{F@(jTo0AGWr(69{y6T}?&HP{O6mkv;6J z8*W=|I>P}Tu{OUGgiFma>AMN$Q22(4#Xma7*b54mGR1D60>Y)Hs086s1IC0)4Mfw0 z_BXMGOAUkWhY{h@1ke#KHMo9)UjvzSK)95eUwSn;(xiBUg@j9) z&u!(PTDY_TYzvnbpeW(e0%%mYv;Zv>E-ipZg-Z+2LgCT^xGh{-fZ__579bhn(gFlL zE=v|JC4Oz9aOv-%nOWxumy)Bps5|Bemy*qgCQ?-SborehME+7LBo`Adt%6FWWmUqZ zt~C@cWiwBy$-`zI?<8K0i#ue@m+G%%OPgiB#jqFkfTBabQ1Hn4DM6BV-Z6+c78E2#_|tAKFn zC5b3?3WQ5<02ri6wR4pzAtqeXIFHraPw;yaHF<-nfC&jx4h1X1d zg)$10+7Gl1g1A``M=50B;87?kk#!4MSEjvPJp&kTL&Jz!J1o2l<)sCsRtnMOU8Jrm zrSCZ?H9aA-h?7NFq>=H#Q=5f%@fsAdvclVY7Zo*gdR%z>+;Td&oH`QPoe^FqrP3l* zq|`0K+dm^q?Ggu3D(XIZ49Du01#=Rl1F~Q^XtM;p*Hf(MQ^?T!S(Li^L3H&R?;S6r zk`erUa7xKYdGC_Nb0eWmC?28k?jbd*bREL`;pLgZ8G231dpAi-W$Pd5sMih9sHgrjqDS5qle+>3N^Z=>SApy+OKTU23JDReg# z_OSO>UD)SzVL#P{RYA9Q+x3Zs?No(5rqC%W>>=;xy0C4?$~8MeALvB?nhN{h#KLf* ze43dR@-*+I!anR>gr4Kmyj>Ue30>F^sj%&e?w;mmA$A;4$Q4%z@f?)0-RsMg{O&T< zh}*8TV1^#jkPzoRiMqa7^~XNd-QEwqFQS;8QTxU}fSj&I&-*wM_58L+Rn`dz7;pD3 zM_1zC`QK9m^E9mDg5gPL9unRr&$|&N?V2HhX-d-TQM-6PQ=jR2*1&~yUDNFaGov?* z%j`m2OvAMMZ>2H4={azVB%RtacybtG&0G0c7vj@4?;mi~i!PiLV7!h$;x2Y-XiRvc z-X*94{sn28y@E8&j6s^F+6x8;ucN4c^AA{HP>#V}1NYR>q+SBqx6WK?)Rq}k&VOl&l-3GYW-nTyAVrmxj> zt^kow9y1{hf>o1J)I%`dAHH{>71BeHkCNP)om4SgI}ws_35?hJ80(GIXNr6#7#tX{Sn1H=hdwU$eKUHWfQ=wBY?3 zzFNcEZna>}xm!Ur)1ub+*ZvaR<>=?Ei`(zQANuj`YJVO6(9hX@dyn&w7e=jH8CD7P zVc(}gq@S}>sg9we7+*sEE+9;-< zOJ4)-tjEOif2Mp6^>ZbvJ^ieO&#zXK>vdQl(!UA}n3R$;FQKIe^u<$W{}+%{LFw{T zRJy!GE0d>=HqrH$s7&rNB$dfimNI#1M43GGc1&-0MK(Q&-$6lT^3+GXGTeyL*EHgQ z4|<0(BUlcyf?2EeQ!6O_qQANNip*~A&O zGI{FXyc=QcV7c#urc)sZwnfQDu;TD)F(NK!nEOG zZzu4y9Dtva9h))Arj`nG>y|#M45ciFbbldO1kb!36G1CFQT)f zA*e`;{sZY-OARnpIT98 zi;|b@rvh!0e2u^4QYy-}v!p~xmo!I2$xFJW`G687FF8Qzvh=4>cEw=(k=FKJ3Jjz@ z%5U+%UOt7zNd~WJj!a1z14Lo*pDceRb^t81lr!+Z!FE4=M3}p%hK1QS~-Z^ zA|%q00r4orrr%n25|zsIZtj>wM05YnvgJ4k(pzNuE>5R2y<27aZcb-2z1w8^ZJf?$ zdbi8;+d18s>D?jI@8I;B3_bEfgc^0m?<}L1XwGzB-#P>B@ON=?Tc&^HL@Q3`p0XDJ z-ATzdB;U=+3nCvE|P#78-C2ar+We~c4vM*&DY z#EE+|eLIE!asK?FOyBv!{{(-2DATtYXY)x;d|77?xh!DkU^rAFRlSzq+BS2GDiHajY6I_XoBS55-jw4W_Vg|hW zUJS^x^c;SdgmDC0YU!Fk}Eh+Gs)skaZDFu1lcWT`T-7{(xnL z3?M*R_{LgxnX=d+1L&Ryk{vRDRyHu5ND3JsXEl98JjR}e6f!{B)h?vIre;>T8*TvS}R+1D`Pn zlh*THk5k)3I!D=Xm!VPf34G)mXCO-GS&T^MuZ77cdkOZ`MfwPR^dF}*KVuW=tJ(5> zvPkLw^a-~78kWU_-J7@UY!TV4e@*GO3e3G-lh+CV+S1DbiVVxy_+zCVNTtOR$@Rxe z12D5oiJu+7FI6LH7}17Gv53a(oK6p7DXs$zq})IQi)e{*yCzaM+JOc#_q+;_v~i$; z%)4ojEYp3>fd(=SyiT!=r$lC%_dm#5mi{IGrlW)e8E7E0(yPQ49hNoxo0dYFp#u$M z&f!9|ISe$ASzG>+mWeyb>)Es@Ll;nw%KZk;on@QJ zdwZeZB+mqL0huqm)FAo{-6> zD2dzbS7h?%4M<`^@l~0`Ef#64DZVDtSx)1A|8<#eA%k*2e*$B53VVxG~(G+;v4t5E;PWz(3`E5gS^dk-FH9R_c zyJ#UM)tm8wPi>JXjVoRMU@_n-3^{;@UuBUZ0X+Qb z7$$2HN_YD;HX{_f#0s%byI*Stz;NjON!fpT$KWC9b=|tIyRsat_Z_%OwJp2X= zl!Gb^;NdThVHk-VtAs~nzwnpD7-0Ype`yR;2REa2nMElOz{6i|aroTaz#IMw3r`5( z;Wt`1X)P28;Nh>dc+mhJ{#h;<4dCIQZQ)w?*o^(A1QeG?G=PV{swhtf@bFg`rOEIT zSZSS8l%|4OU;(zKC{G9Q@Yfcl$)lpQbwz3Fs95ElTa+h{3flUjG03QC%!gLb|z)Zd87p8}i22|t& z|ANBYuxQQQRhS!=%kc>O3kx&DQYG`E!b~Elh!+0Eg=tOz5C4++h#bJf-&@8^XD-EJp4<~fE@<#@Vn+`hvy&%b@%)^!ZVOL4$Pk; z7JDNsVlSreo<8CC`~`)WxD$Twv&e3uUHF&HpRHibjo2yl{XZ0Dol5^-P>gj-1Ajqw z>*xm)v+I}~e5p~3^mVqi3;$42GTl0$Ood=@!arP;iLXSh2m9dRj+mKNU5*sZln}tf zzdSjI9l*oCqATw7{J3nW-$r`@bHHdIJ8PP0X+N>i^8|C zNQ@5QAGa70&<)_>pRky*03QBH3oRPJ!yip%+5tTLYb;Lj03QCel3F-`hd)}++bAw0 zA%KT}jUk!^oE^Z!zt%9qrJEg}!yhw*un31R?h@?y9Q=sMpD0Yw0X+Ok!zmEJ!=Ew~ zs%b(15C5+WrAPn|f0}9hbm{Tc;p3+Y6^f&+2XETTFdV!6eYrJju!jprP;!hHen*ZT z?~~!!(J?##?&Nfe(n#&+luxPYF|aS?bQz;V(UXgz4b%82gp~1oQuy6$D<|8~ z^~!dDZ56P=HQw*x)FMjZFuk10B6VzLZd~}6ak?65dM4e+sai&b-_NOfq{fa9ais>> zl80sT)WoFl4{~}j(r|jk9L;CEl;DwZxPkeH8E;YsdRFQmVbf}v1z)%>&+SAjtw9oBKC#=$h*`fGToum8Br=jeOPVoUzwv$IotQ2$iD%^rf4`7|0{WN zz-Y3=srX-I8}_mjLx-&KAIraMExL`vsrZlQKZzrV42M(kzm^}uVbYmMI2HfvTx3PY z4X5Hi$!0i_M8m20-(aNHLadl5{x=zgvx&}U2SxF}#pqJyALE8o@xPs?R%{GGC+Bw< zJS!6_tf+7*{&%^^ChY$wwu%2#{Ye*s@|VIJ6dLMQw_wv|?NnucM-l*(Gkgj)i;Z@%rj$ zybgL|S@XItufw|^MdEeTg=(h>@j4c*eKE2pQ9|vWMe8KRj@MCnn9iw=-c^%oggRbF z<%4{({1TfJucLC@Gl&)~%1&5D6R#tCP&OHtV#n*q{$ms{VlvssEKD6>i^y&$u@B3$ zQuaQ}hIc#_ncrE@j{1h55U(Tqh=uE@9NB%PVJ6ueA#%GxV(~h%6=h*ICtgSPWCVcp z0ljjTEelMBSiFwxKijC(@y~XrO%9{9zi00FaXeqmz9v%`MceHvH!z=9yo3iWN)+8H zvNtR+B>;}b>&V_(;ox}FH;mVj{i%yt@j9}H7Mg6)cpcfLiwuaVgW{8LypHT!Y`~4z zk^N+)$wY5lTJbuv<5`2@By>=YY)zH1OR@D3dXEK#B84KmvO1cB-xoLWIQz*{%!>XbuvMr6NiQJi=k+4VWA z8gS2y#_P!55+TImb!7i!F~WEq*^_xwFj+ZXNA}5xRmJPb?r$(`Xmz>qITAscpX)>#wvvt zOuUY&I)mBqI;!fE>!@06LAamrC1Azts9M6f zytZcNj*6!>=%f!uf=Zm z2*XCAksCtQ7K?=0giei?0##crJ2I=lOxrALEM7;|b_=!cA?7wvwZmeN6OVQjt~$>G z?06kjJ6!<7nYB7N-ays)E@;K;sJg&~NYv28>!{ilLuI^;f`gN7W^+)s843s&>1ej@MDu;@ZPd529+1i|FtUqN+6lB*g2eYD?fm;&oKDyPR0O zj;g&bAs(-zYM;x9$Lpx-a2dJ{-7f8PNvZ=}&VH9;x2{XP)Fmdx>!|8-InF?FOY4p? zN&hX z3BSQc;&oK7algGr;&oK>m)kWaUI%?)t`@21T!?SX2&JInb1PdvFrzqIY=n{)4 zLGe16LGe1|2gK`;9}usDDTvo04T#sl28!1qEflYVKFN3;^obtkal8&naJ&xsV8!d8 zq>k4?pPhIeWKi)sHOmL1i z%`m2RGCA=&$UyNr_^*uDK_BDsI@VH7D_#es!+0H((D6E$sN!|dXDeO@B~82zD;37; zAe$YpV;QdjO}viU2YCT5&3e^Rd%+5`(x)|x){3m%-)MkHypG!cj9^$K*zr1QU$xTY zRkClQcJ!>6Q7!mtKWaf?1+F>U@O8Y7+9RusQLAlHypGxrSbz?_QF~;yVXJzOxTC0T zSrY@oOix=_R~WCO_I+zj7CN$t*HQb>Iv1jcZyc|qcI;e(*zr1Q)9VdjLT`xL`;A?0 z?%3eWhNMheMD05^hCnnI(2biy)Q;Ct`>TlEiPuq^-)wTZ@j7ZBmr%iY9ko|&Nzuy} z#o~3;4%(dLcpbGvHm5+mj@n~3sZhL*+7X*oC|*bH37b_YUPtYy%_W zR+ths6SW;XO|i5OV&Zkw{=$Od@j7a6I-hd#7IZ9LN8P(jsrVW!<8{;>wKkiz6|r;H zTKmS@tiSivJz;^dcpY^YS{uofHQZ0DyDfs4cpY^)YX=#bRG5moXOy`>ypFnO%4n^# ztWdm;x<4!2jn`4vWNixLXdJJj?v1X|jn`54F>B8lS=86_FkVO9DQnl*;7+`bx~0~> zu;Iv6Z{6<_LER8fTYJVPE63}odyTaxOs&oFI_mDUwu7yB9d*A?w4=+{S-ZVfypFoZ zBK85PVpeyhwF7MUDqct3pDmPbLpokZ-6`G$mP1sHcw8E%M(N$A`ffRVafZd?b>yCw zYurM_@HtKH7jl5m0B~b+h}0!K%+;*$8bz}~adosa_BlcPw_(bL^e${GyWd!viYagAD#&6N`F3F6@ z4O#o){CXWf`^kO7GRw2Iz`wQjz+>?`a*ftTHyuw)Lg(fpfZDnhxkoL)ir0~Qk+r|g zhwqv^A##oOX0zI3p?Dp+=P`h{d*_eWk^gTVNkypPSjzu|sdl`M{2yrxP%c#y<8|bP z7iDm~j{G?>yAEFv#_P!csUSz>kEfE#<#-+Wxsn)W$Lq-78^gn=$^152-uI&gn79Y| z*T+B|MIm2V8qG&rAtHZw%uYKN6t5${sw|pC-6*kECz0~$xnrbCA@aA!h)%qYd@hI< zq#Klmp2*)E!^3zT`331{UKOt+e?tMpJYvoNE=IB9b>xRKR?#M2NB(YUFC4EUe^EK- zl-tX8ypH^H%4t_%S%@UY>&Ra%S-hr;#OuhPu*;6b>&Sn>&1l8s$UhOuXJZQ&aIN(5 z)S$59b>wRoSZ&eWrTa(Z_a_4gF?64cgd?q~!YNAGk>Q0dV2#@!x(H7rA}=5AsJ67@ zb>ufLv|2eHucP7bKq2h#AuC{AA( z4gB{}*op(u@S-T_gnMXsaTK=YwHsa%MeTqP4KIzM@t_b5FN>1obE|l~j)ofxF>S5! zhMOddN1lAts^WDtyw=I@#OrAIM;oKoHLdqL8*=*X^)?divp3jaq`z*lF}JU7wIREo z-e?2ZC$-~sG`z_M-449XhMewsvx6jb&Fzw4no@7TG`z(^)EAz7QxQ8goiC zthAO`RFY}p8zKljziD_XVw5@p;e)(}Icrfy#kn{%>9Sy_Qs?A0y*P|9j z{bu5IG_+U?ItM~*ppO^Awu**b){;*}si0n0J4p>6bKz*bj)rDyVQ9zeXn2zaP`r+Y z4c4*{2J>~R;cjcC4@Af7X!t{-T`$fW)>vytRdZemHr!vqNPeg3NY0 z84TlfH2f}3u;O(zTw$$RRpACkFMLwsPP~qW?bfQ5MheI4Xt>0(>N!U=s8DcgSDqcs!=Pf4@eXx+ETy`2ptu5&SBRSL9gnIrM!hCeV!at#_L$hcZ>ws#Osg_h6xmo*RhoMkP=WgUdK|t z!z9pDypE-E?>3AJWdD|j^ zP#|8%Ql9Ip6XJC&`=|Fp#k|If*RkxMS)sA!m=&*M*;~m58M#=zj%9a_Bfn3D)J5WT zEMN6+u9f3;M6D`bhcfe&niQ{N1@A`5-8~Ce8+|ik1rLN0=)OVm|HR<&2?*~tHj~~a zYq8m(6ms<5Ks6o*AMQlNh0X(edmui%q#nZ3HHTzif|iM4sg>w0B}pk!gX?H)@&wCc zddtY<)v$(U&vB`>Ln|o=^e-nURl^&vTA~SMDU~R11;HgXO0TEqcqry4{YoJx-bgx> zq}FHE&09&z{)UPPxd9HCw>sm+*} zi24#qJ$H~^A31T|AjHQ+aN@)HyFA+`X|WxQAi|jJg*U?hpBsB2<_)hLvk<1`xF(nE(gL3i12CB zR}1n`$vkkDJivPBMYlp2do!eMcWs8ic(d5@Hwrrw^k= zskV#elCw?uZ&l`PioQ%?4`{n+?y~5Q=~5)UdBnngYGa$l*6S4Jp&j@XMDtrL`Z8ta zif$I$?o`-CIP2yQS;W0MKOJ+k*#0F8qjI_Go9TTF5?@-cd%3^8L+Zer?t3mZu~xB$ zVi^DPZrh944?FIlK6oxkvAz|3u%Ufs783NMGbcx;<)Z~}kY1E{egmka=;U2Z5>{6& z237A+kFZZ0ZPj^0#JymN)!E1B(7C00Gz`;dC|RcaeuU6>A=&&krLj$Ye+d-Nt-jy- zafS71yJ-G{MJKs+qU)Yt*eJXC1==o}H!2gA{$^#?J>Q|Qd$nCO-(b-n(WS^<*!CiY zad+Kj5r1tHn?>^nEUXGG9aeF(X#SFgZBUr%&h0<5u&@=-&0z&M{hk{L+L?& zz)bJ92yf?GF$XaDj1H9Ce4a}5Bk>D)2APuPKH2i3`Ck?MT)^e{!HJLv{`RMo zeN@`ae6|@H`lnEz^GG-o;TqJR#tV1e+b9J6cvtQ`2Y=|tTfOt;_(MNl)6Q1>p&xJ6 z`G@d_e*9C*#HUx$Ec*Zk?*EQcW3Q48qbT3ni1asDsUn6F0n z7tokzNNUWNZXlW^G+!1Mntu)`LHa0ur=@7Q6!#v*%YJghU0m%!X#V%8dgdpMDDFXz zN)@aEZwbwxhnc{aMq6l}%xN;q0WKgkzYnGgGD)HNF(jKfqa`%|H!yZU&wKEg7MiDn zro9EO&^#F{JgNH~7n9j0 z^Q1k#(_3JK=HCLtZZc@0`MY4~AcGc~CqpkC%@vyeGRzQ~*L@Z$!oS1ILasJQ*W-7E z>@$U_4qIrt5RsGUp^3;sXnqv@azNCzBsAa7-53`89`56`DAT&SmeBmU$hy!Gnty}} zbA;w;+`(iC&GSekixHY9lP}6bq4^h}m_;NszX~Tyl~Y3Vltf|L@UV9-3~4z4Kjl%Q zXUiR-c{1hED32mvkS@Vtg0vj{!Q6yW?;XW6rpm)0(ogp5U=|RXucWi1A*e`|-$42m zCSAdi4R8dq1!+2|Aiaive*~7e(EPh#t%wNC2kDQ)Y6;E%hzt7(epme#zpD8%tBDHD zUxHhEtr421QxUcOqbCmFZQzo986rMmRoN~}r(7WvnZQmHQ8MUXaXmFm)cWUZv0xfCDjguh#|LY3;$ zUILJhEPPd#UZyNYrMk3_E*OxEN_A;JO^Yy{h^thW4#+0aSJN?mzCH|*XJt2P)OMosp0+cvjStJU`?qqPLYB&WyA2LD`-(#U6Dq?`h!4yvKQ2c zuB54?L+7LhboHTk0+KeR4^7>Z*R8Dep?P|-jI0m+24oG=Z|2{0lrUGQ5B)EUeT;w8 z45k^DJ~S1g&9*)?Wz}}04^0QtR!bk6j-bu1KJ>59p$1X<(6;fqP#-#C4fUa;cC8Oh z_Ig_%nl9En@5jW2UxQ!NET&3II41lW{L+GxgFh~ehvQD;?QfC5q=Fytz7d8zXoM7c6es!`Ka(~5LonN;nyH-QKWvGE+~}J3^Ep{i12GrZt=o; zNzKqbG2z!>fyFK&{2EkPJRaVm_+_v#3MGubMNtl4Y@{7V!mmMP6fPkA8f2qH_Y7J1 zHK?*k5#iUMI)=%bgpzMTjm?M%zXr7ySU~tSsIxe6;n$!(5q5=NgPcVwEc_beEm~Cg zHE6IvIjBP6*I;oB!+Qd@@N2Ln#t4O9gQYPnD*PHOvnU0GUxVcqhsTU7{2HvV@C4!4 zpwYsM2)_m^EnZakH8{%!qr$Jj*%q$#vdq|TNA+Y@;- z<*_KA7JdzOB=SP_u#k6NL0*#ZYp}C0J(Nx~Vt>K;h3TO}rBcicE-1_mi`Lv-g}Gt5 ztYaBmSeO}>Dw!7*W)eXOzXlfBok-(*nCyKm{2H_rW@3h7;n!eK zVU8Rh;lOMy%(PFptuQSn{2H_uCdY+egT0CD`GjACee-8CJ!@709rI@khmIa*o%81j z52f?$pFfWgehn@?19m9<8g$Li4$naj>hAe-gl8ag9GE}Hyuz@3ijwKpp@d(9!$q0N!mq)R zqL~teUxUk&bJ)VK!4-u$j__-6Wg-z1XH@t#c#g$P7Jdz`vM7ndufcOIMuPBbFlga% z;n(153oao18Vp$+y^uvOwPIV(6@CqlTFgY@*Wj4NC?NbA3@310;n!fqqVO#&qU|bz z;}#@}Se)X*ufesF>dLy>YOTR&J#VA9j0EA= z;2J|T3pl5!YYih@y4kv}!I&Y0ML2|Umk<+v4JHZ`wD4;%X*dOhUxO(_p_(QLzXpG0 zC`E){gK4HM9PAtD8VtWF_rvv%0^qi_?>V?nGzSY-T#U%)<@}ORP_g1+>~M;5e$j1m zdJi0DNiYqsd&2KV1Pd8X0me(Ycy5JC?s7D2PFNH?+m|-6;!Uc6Z_TK za=cJ9eOf+e39>65#Zel|$yXb0t9WLkfGP%>u<<^0VnzhjoLrM!8xFP@)NqZ~m-kN% zO^;Vfi&g|~Pu4w@->=w;HM!iD*PkMNdk!*hpB$=ekNUUBT@MMYdY zavGj--m;37cw+f86jkGbc#hq;A6PAj!dpq>Nz@KgEJW|D7SPkR6YS1&Hj%Pu!vKF9 zs8k{i!aWG3pF?1#?D_GEt+x7b zdTxR{nYshR<(RkdYp|Lr*?~GHEQS8;h!RvNxGecy0WPI|}NLYyQ zTIey>qfN41?w~yQ=iT-nD0m4ElNRcb6F8M+Q_~}-D5vmR=~$m88?JL{Y9mt6QB{LvV^yj#KCUsqUMx0v{u4Gj-lr?rkwt5?(18!j zYZZDwB^p%XqeyHxS0!+C^2HKsf33WXsDpOn$F0`J{feJZ<4wn>M@9ty%KXM_UV$#B zpM@Knx8o1}c(u*{(kKM|ESzdChlPF?p4&{9Fa0cBzlo*^NSdoZnO}R&PXVBxMel8X z9DnGia-;aRARmyrrI?t!eFqLUww`}}<9QpmZESAbFur3Oe$CEJj9herl;B2>AvrXC z?Bqq)@7%G0z!N8ik2Y@T+0wXSW_I`@__v;azNpwVH#5CyX8PEs;gO?rCpPiKxntV~ ztTwSxH<0Bh(Y;4}xykYaEW7D&n;K?GWJR{L%qCPe@rf&_(Z>I88x6OnW6!>&detod)e^J> z{(X*GPBlZxmtgQ`MxQr=TX^d1|3d0nc>MX-QCm{ZqZHRW+2gN-AvyMJXTQ?8v)?ER zDN9p0^gud}VRXRbiu_A#XFrO)p1ye{4)~zQ?x-2^#Iv0JNG8sgM%&qs%xN+kXTJfM zD##?A{Z1p<#2GDTzZ+rfU=Kj;>_-Ppd*!aP9~mn=@Fpit#hv{qP?}%{m9TuM{}M1 zz5_Fy{dAv&UU~2EmZ3As(r4rM0@-J-vtNbjLfhGoBHCvFvFi|={rb>&A`=$-9*_H2 zlxp`R%h_)yvQ{|Geos7cdGq`z@lgqamnBi~a*?^5Rr!>0OE=kgY6DCsmfdfPa4$mYB0&$%kNF5OMY^ zOMekof3UX$o>qOLWDhycm!*G?-&wyDUrYEhtByMRbpfg|&VF<%q9%0qqdY#tp|jr) zz(|WlRODg&)Z$GV$_{*B=%^^!PX*d0`30}!QYy-}D`!7xjyd~DvvKyLbbZ=4&VFR@ z_gqfVoL)}N;q$jq{}ntU+GOIDbT*;mpWiF#udaY6URnCfsHY$L0zQOPS-K5;elchY zK6rd}iqdm;F`ceM4TZjd1Zku31tjYt>bUFhp;nZPNtWdcNC5I#zJSVN`vTJS1d{Cw zNLLh0iN1ic#q`Byd;yi+`20y%ze6-dQ{4;t0@C$Ogt#vtT^z-H0sVvI`^O5GWt-`K zA4RVck>63$#QsmOdJ@*s=|l zf^L9|Xp)%(gO5gS=ehw70+Kf621q@V(+#ZM0I6+lBf9~96j{sC5A$z2N=OLZ0H0#) zNBo=SHqEfy0I3jdw%q_JtF{|AKsuPVT5f=J1Z{TR02?u;4WirtZKH7mj95cAz^Glj z0g}DWb_1mAG*{RSa3NK)up6L(3%UU^CCLqt0X*JJb^|mevlB_O8=xU2y8#-UH=+x; z0TyOq7gMtOwf3~&VS6i{#>?6};n?8@Xy|9=259(kH^3;C;E45%bwF7_q8nhe zB;#fkjsFfez$n>{{|-06C~V5=Io#eSUA9sdE6EMelyRnRfM=2;?gnUborxP@lpUTK zdOpDo(9jFI0UC;Yny(A8-2e@zxErA1h4tbAkr4kKZh(ee+zrt1cz7FEsD)M$3?+=d zMNtl4Z1f~qxdBE>FYE>wA-ZR%-2e?K?gkjeWKE0%K#f&Z?HdLLkhRQWhYwk-{A&mXbEnB29$%!b_0xJ`c&EdqhG)cFv_sq0Hauf8=#>Sb^|mV zKDU?~puv;f01aN;4bbos+yEUg!41&h`st||`%P9WX%yE$f*WAG6vMOJ0E^KqH^5>v z+YPW7&vFASMzh=ii_vU1z+ybh4X_x^aswMQ(9q^_156^qwIb>U zSdXb0rhU3?iLJubOL7A&SZ1OdU=sTb+yLjz zW_s4F0y+{;B>8B1n03ydCp?tSvw!|PjvL^-Cxa;hZy@1ojDQ>9yzI#E@18$Lcn0z^ zI52;XGjRi)x1zB^Ebq16XHf^sXYR83vppL(zFUW2k{a|AD zf^L9GXROIQ$MYN_;09QXS;@R;#M}T4h3^p&Pd{=4G>ixsa|1NY zBsV~V&gTZ0$c(rF8qU0KfJ}9r{2brC(fR~NvKwGXGz&PVsB067a=iS;3?VGSA&k3( zBsV~(5;nnd0}MHZ-2g)h%@oOQfFY&08z9jZ(es7Bg@2OTd)BeTtytu{gMGQj;FE#C z<}&_!(2@H#a)t5VgHBGX`0v4fPKEK`gG)JW$A1sH*yO~254zdr#D5PCuua8(4|+JI z;=c#IoC@Q=2bXbL#eWa_IHlsh2mPF?m!a7y{(CUMmN5Q%aFEkF{(EqU&)CF&4-PYK z$A1rwuqllH9$cOycR?%udvHbW<=DbU{C8?D0=bb9|DDpm(CMW3@4=Nh>J%Nd-0BS= zs~TyWop9Y-6ftX%rgp?6uMHl^eGiOG_t3GEh}bKF4{}8j_kC{s=*V=>apj*0SIQ4D zl1lGeiRa+|lKU~L<(t^-{inx|PLAPm8H5sp4>OuJg)oRR{*?h8AzlXX8yf2v8KTe? z!AJNA+4LYC;XzJR>v;Eet%Hx|&PAp52~qr|!M08W3>)Zy_Ch-NW$rwbkbWK&^D920 z;F$Cx__eIIE;N!e_)YGQD0dO%9>x#%KxKHGo?h~LZRt{tw_}_5d9WdWa}zh;iBSxc zjd?lNyN9lsoTiW{BhyM}53k1M>FP;ky6Fi(1Z!rjge%!|oE`>?U~^u!Fg;W3Io=t@ zuoHjyVvV$K=Kg2{K#eoosHxa6$w0K&=x2P!UY{^vvwYc-Ru>b1SWp zEm4Sc0h89rlDJA?{#^{Mm-$`jLWVZVT>W!L@wCc5@VUB8iKeZjYQOLKZ9c#8iz7Q)FgZvf=lxQxMZgEr4_$eg04JW zRC=09Bs`9bsVrTDCW6cJ_kk1)BBtTK_Q3;)K*&>BKQ70#7aYqUT7~No5Bn#EX6ML( zdYG##c%(Lp^Hebu%jKiemJoj}jN6)N~8kN(;lWfkKc{)VC!APxzkkcEk*U1TV@;4dH z8x%9v2>gR^PXPKYMwgoLVQ2j|kKV=*baH-&!L#HP|6MMoDQwKh$p=s6zmIb-OH*s2 zSsz`p_#ATL#UKj4yo6@QhMwus6QfYdV_yq|7bC5m#~2D{?auDr9ylJh;VEHXXD{v$ zxaoaq$xSF}$&XRGkoU7EIFp}22s1o?#+87Ja&!XS!*<-sxc$GzsS1px>6uw|xUaJ< ztH*u(aKV#YZ#`lX2;W%pc~qw?O_jX_~K^}?lS@1T+` zs@OyRA$4I0RJs*J!k{i(d+wTKN*K^*;W|m7;7|uAuAP{?ZbB?NOqF8+TN$D-1RmsC zv+^y6$kT%Pi^e^J=txGD6PEG7WN1Dp&z(zYIf46+3h-6=k5Rxxn5lfs!c<9HMCFDO z`>^bXTX~;lgYdH=^GhC;qrTxok$YqsLl1ADOsIEQDj%`%?zyqq(aSnT<-XD|lWdL< zx!oY0Qc-+pOt)2KMOm1wlfSikI-9MTw$YMdb|(ObLJyIed2L zdJ{LI^41Cm$BRMNpVpQ8sf+c`&K=dzp@k+}Z@(I18eF=_fa-iZCMT~Im2a^D8C6fm zW~lsRrO8Ax%p=oS5V7FCs2tB43@0J)C^Mq6rpnm&vCdfty~l#W$c3VEWpy+MkBQ@W zcS!;y^V*JTs^o~xA>^VJ)f=}j6!DQ{4q>J&%h_!8Uj=mXH?r$(`EWrj&;_4hm zHRSx#w8Wt5JvdtUhjqNq!uJl%%pzDX!k$cs%3!I_q-Re5uZ=uxCM{(+hM`uqS znCu(DEHRBvJ3TPjGBq`Zg(FWGfvrU7;eIH8wKncoo?yV@HScl`gW?#>keCU1I_I0vFj@W7U(Xj;@of zGg#YkwJIJ)DD3(q`xcSSCE2%%Y@Y2ZG(&iE5ZQ)J+%gmyda&gL8eZQwM0T+S!OoWe z981HKS;Dxywz!R!nq#YmSY|AAC)g+7@etYNuDye#&8J0ng=^M5F0zdVKso6xnr-o#RZ*UN5reI%aBE`npQ5l4aLh z5CupYJ%%Z5=s4CIBD*1mQIz@YMrlU>x3(RhIW#$j;zV|nMQ%e#gO+3TZmYhYv&|Ol z-XyY{EeOL#qLCXyc8f*AY(l3-OM&cG%Z|))qR(!#tmu4v1)(cpR-xN1)Vhb5+dy`Q z#h~vr;c1*_0j;fVSVNCrIz2HavO8S>!~#r< zCpbCnGWNL)ZU~pr;WBg^x};8*q&mRm>~}eK>$=2CU7~7fm(%5PoPpvpyJJiqG%o3Y zOA0&DW%al$-Jve2*Cid1vzyDg%;w-a)u@`!`fQjk4~@&~r{9M6O^=4zB|Komhx_-p zOk)~Dd_%tW4%(pHo|C{K3+NoCuMo4R4^E5^P0yT!9)0$(4Nssx$0%^7T5-_5=ZHn< z9X&={FoS09ygUJIpEzj0kuuoKf zzykVltD~_{ePp#^t9sC`uBdKV69d9bPg__Q6booAJR_>#x7K8#Bk%3$>uwonA7~ZT z53O?{sub}XIGUaR_X3GurYgV+VeHFTO*`P1XP#1_?8 zZE3-xF((NK6l(a3eOW zWo~$MGKqDVfShv)mOw426@CX<77FER+I`Vi{B2y~E_d>^^b=3xkPad@r4tq5YTY zk61YN8pn@L42_Oq*NL7LP}5}3Gx^&vzD{>^!poy`0$*F{Ye4l&ESzR)G>@#z4=o_v ze^BA2M0LkbQ>=OF#B<{>ET{!)DYNt}sQ={LEPn~DzUh3*DFatgRC&H))s<57E>kKn zjy@@Bj#@i>+PX#5thF}lv|0B-%@Y>LQKBgV&)Cpu-l46z(AvGDtl=g`&216Hd>N_9 zS=)BVq%QrMXOy|8tDU56X6OdeJcxI4kIzhv91}Iql+g_)*XiQn4W{PL3a7nM6pN=y zXeUwAWbMSkOpgLZ%^O`~C!Shab^n;PQHLz*JJCV9^Kp@hPC#&@=1yx5?$GGSb-JYAC)&~F>#Qv{`qtJz zIX8U_1w9tA58$1$ky%l5rM2y5`0Dbn`Ll)6Z3sPdsJ(BGs5!-3Z*qvL5sypb6y~sL zQQIwtFU}CbZ71b4tvY_Q-SKr#%Y{WDVmJcoejx`44FHxy8lmENtEX<4H5^@Ri>Nzl zZ44W*3*R&A?z0Ap10maotzn|$Qi-|;tieHzaj2!Qv*o~msC%i^=~OYSo~K0JcB`{Z zb)QVI;)uQ0t|^hZieI%_Ul~EY$lAQ*qhYuC#0Y=+oDp?H)+Qu}6_>5_4a+Rg)&l?5 z+IZ}ro0^)Op0&_MYj=^3r*{|Y<|2Svy^6X=EdZKLlhZPMZQYBkO+`LH7rvv`HQGCT z>igK9App-~0B@Og!~17&boTh*_{{a=V}s537nwrp|C>ir5o$P=>VLx2uFgFeP2K$n zvo7lYNc%2wsY+qjd%8QvvDZnHvRq=+L;WbiI6%Gy_2f(gA@FOzy41JIimh} zDydxhh9>IgN@5tEo#9S8jPD6kqW<0(jvYh!{F_&=^}Zi1z(k<0e|-$p@$Bm>OQZSd z`=_YCJ7%Y^iD)EIzp5;nMcpW|Cg_});UGZR4i)vc$B3=8c2#~6qCOWy3(^frLr>J- z9K$hHsZLsuj^=IWuU(@4h60Fru2uiL7=`bNJWNIXP{t~HpbOtnNYVvOBJFLouSm3H64yXp{)DpnG}tX6L#4I z4h-~$;1}GCZT&s^&R_pTB%h5fT)?%`$5Vp>I~`-{*<5|?0;?@>wM;@=f(OC=WMGS^ zzt2U&k=9h<6s7FQ@In``#_bPXMDczHwQ-@<%Kdx#2eCbX*!B8*U+(YZ z)v0!(fl~`(@Xk&i!^4c+4N-WnjXpn$?wg!KfIO4^1yKUWDmVBGqc|AuaVS^(< zv~xEWVp7F+`NJ7`#E(xY7!%^`T3sHL%;ib@PeIZar zRCG$@R$5CeD#=v;h6qBN=DDXLM%wtFn+czunHHJYU^>j%0dL0?Q}9oU+=LgFe7rmixc?EX~*aU!B<$T zR#mux(F>oHI6e2H2BawSBDdXIwHoUsmQ~L=BBx#k;xVtSlt)(o9&3pkMQQA;wwA0K z*TbB)(nRiKMHnJyFKwgwsrZ_ZU$J-}TR{QlBvWKkA>}aKLw)U*`p=eA;$`QFrxp~bS@~sCE(Y<>R@7%O>b+@#3 zbRKBGqUS*S!2|RbPJ5fk&00Ixx>To0A1+Ryv+HV#pPf|(pV?J%ds{7vCXdhJOYkgq z%tY?C)n>)!EGQnaHosf3?Tg2cG*ikEbNxBynDpI5FCl(p+1n?e@P>I)V&Ob?_ZrS> zw+}Yw_ICDl_w3mZNA>=ez3m84p4+>!H zeiGftf3RD=Bh)7r^Bp0fn7v&+y}g%<#e5q`z+2nGB6!wMpx`>|gV!@Tw2H+%u_ut= zW*`Z?ZIM9eZ|`eAaIkxD&%u5~oy4j2wUArvVxH@(2k~xmAMIE|wDPip2xKGDOaAG# zeUPjgzE0m-#FBp|_ghhO>}cOB$>Ft`OTDf@yTVx~|j7)_@UDSLOg%1RP4MP=THB<+sL|X z6flWj{oN`k&Q8Kb+55zw(Htud(#KC;59|B!(*p?TKR&@g?N!V`txD*KD!x5KI;yc&!%+K`49tb+C#tg;n%9$ z75AGUtcKj}UsH9@*@)Er3fV;#{PP}LgULv|6Gu6#6Cc(_2~97iQeQ>C-hf~DSC;-7 zelH#D#50$P>u?X2kDOZPrl)Z;lrKnl_k04?dTNbqu-9-t9PGB4gQTCVwsO6DsGYt* z&A`p}9!jp8J~gEA_dYK`rasw7_fjKqOZ-3;n+4swe;10BEkWsMOQa($aXnS#Txy95 zh4fM>4{$3qpjWsR&L(60%$E*gF79pTQOIf)WQRU<~eKC#GX&@_jM81Sd`T!+wqyhR;k|_H+lIPNyY*R;g3P$fH z+4l4~TJr;unseKm%MER*YA;0HuO1Kn|!1;x*eq^IQ6Wm4ZacS_cpwv)DBbX2(w|8Rvn>XEWD%DWkUQhY|mk; zUn2&v@J49pcHkiqkJwpN!fvYL$^XF#$$C;cTF+N0uI_I$VsBQ+6qPc@BbJUJM=TkW zMyxYT_Q+>tUMro}Q%Z&RmEmd8WwC6EAE$Y(G`C%g;^k0jH$!DFHT_dSQU_b zU?bx zI!6?VH^fGV@h#t)5b`wddDM5Z*gO@xc?xf4syC3l#S0pB=}V~e%~NoM(%{l3n^5u= zs+JZ>rq_PxpLbgwPHhd%`B$NNo8E;FTOY(PuW##T@TX)t{}!2ZN;Ofn%!r&<=$x-d z&TW+QOH>5qZlb)~U#PNB#l;pH2d`F^wy+Rt@ilahNUsxO2i-Ni%eD>TPYcr9uEB?w z(T6#Fco#m1^RSCPHZmd9pXIyBFmVh|n)Ki0hr~}n^u-3;hX3!h%}Jg7_|)d+XRY|% zyiQ4Yt2X-aGQ8%AqTr8!CzW0%ihH*SYM7L`oX__vbnR|c#I*YRCQP?=(6WCqe!S=Z z6AFaJw`rZtn?vRIqN4B6edqtA`>ubEAElibd|`pS`Oy={pcH?6ViKzG_?Et53OlK| zlfb#4V$-qHCx)lta=U4C)6DZ`p0{asd}@k}*Nsl>*cQ=>k0dvs*bOXAzhU!6sV2`d z^Pzc@Jhb|=gGyq#qGClQHK-_Xv|P+{4j1f&qiH*4lB>8S<)Bx zE*(bRP;T5i`d%t370e)Z%WUJ^#0*|T92sr|ACkSL^rz%g#PCbU@Rk7EOVf1t()1nt zTcWNUGvt|>?H1>y!}Kv0j?enc8kR2_ScbRcciGOwxsrqZ?b`1t?F-kZS3 zb(MF+XXZ-dk!8?EVjmaWZNY&i=PSsF=C`#{bjd{PwQKN)^kD4xhva+!L^bSut{>`NEOhaGu3p{5f7Y zJsi9h$5<>jM+9yUcOfgchX^zjZlyaR7R#R?g+||xxjvKqzqvjo{S%UoMoY!4pjl8d zF`S=3Y!*zRMVC>-OD1st0Q~#>1U{7iKEzAo|Bc_}pU1BmK zRKkaUO)3T?faw{6iRVmQ!GDe5krIm}=d!aIc>1y2iA+=G2z?L~wP{-g&9iAc1g#`F zIfIg9u2O!*V#)bwdT~5E3eamj!&sC&#vQV_iYM{Vq`)gz#=IPA98aS)7o&m|%v*&& zi{TXTZj!8Pp2a&O#FgY@hW;8(uT*U!289+liSB#yt;kU|HGG1VefmjsD&8zQ`0|qsqSYuTWPZC`a(^eA$;tWJA?xj@|`g zWnUrw#wtVy%A*_pUuxhAg%Xug3R+@ zMENt)LfHy46iOmHju}<!Cz2tY)#adBfh zXkcYge)Uw%7{(KkX86??AbAA3O8C_mYsN+Jb%withm!Bjz3XED$DBgLU^l$<4;^V3?L2LmlxOF4^0YB9@g zWeH9%5p?vm%qkjQ$(iwpQV2d}7tAWoTq1JvnaT}Ea;rJFLU8Bt@iJzz&9CA78dV=t z(OS+}9;wBQ8qE}jk7lPc&S<2#z-lQlJyQr1TF!;)BFy^^rg@ykkLDSl`z6f#N2EEC zOpOzx%=@+?lFiD6$crFd8h;y~6y;=-#&0!Ok|D#t)o<|I*jC2Y3R#ZQZSH-7SZ)3Yc7g z+AJa!b)|q{-7!F#`k7}qDlb8#@?!9od}k*sF%n%p2Zvaxb=}ql&>OsK){htMTlP{= zSY(J9fp)-wWm>v=GwE(TqwGs}Lud;E#4jvCXc`Mk^!IQaS61c|OLq=hMX|+(O-Q78 zod+1E1DSyy>L*mSt&^1pMcR8Ei6urN-O@7HHApaW8Gu^v=^^CzbRT+gsgc2xiq4)r zgKe3?eqy7`+E~J{+j=_!?4)5+e|5H{k*C5Cdk6dXX1aJ^vr0oI{XkP9E~_%+)}Fy; zMXokvCEe4@Y7A8ggIa5-z3J9W|6UyQXW9q5dALoMa=CqN1A~3t{dg9q&9A*@urIT3 z5QE*>(bX})mKzp^Yv5424|VNp!=op9O1B44<=t)V9W5Q{PPW2`cDD3NGg@hg7(Bdp z*wfn4eweK?Wa=!yTLQ0=tu|D8z_X{VFVosic&dB=`q>)82lh)Qy=RcEHKg>x9y~)w zzi05xNG9Fd+Q%+1-2Tpbw_`CZ#%olrL}Ypw6cp` zTJr$A#HH-*;N8{Ufl6$2S^XC4QkT`<-q+UF%Puq2wxNN{j>auJwgaQI8xEm+pr2iC z*n2SQn0nm#WcsPbm=K-p3L`;80I$oIclKcD39hFLcCx9M6g`{5oRnhqu2^rHo&;xP zPj__pcWcQ8R}$eX+7QtJFT9bye%9!+sVLR&(G(0O=kydMu3``K0_Aw0KZQgBy77#+RMNRl<64roZmmbfxhLMzyA z*xc-U`}YpEH?tjvEOjaen$e*x*iIuPEPpG-2jX+SV+g%@mCYa8yzRG~ zawMBJ@6aQ=+i;|hJJd0-m*zIR#<0?zhth}pGwoQIu#BZ40K;Y18iB!Xxbse$dYx_E z>^j5f-`mkX(8SV)a(x?3%%K6S%o$NucPnc)e9YUf9`uKtXyi~>i(ylE0NGcp)sQXM zm*J0$S({;Ux6sv;IoOfTz#`iXr@LnWz1y4a=;JWZdkjad^0bc->-AoXDeHKE&v@1m zZ ziAih35&&P%dj0J7bSFx}c8NRR=B^HQz=+8G2-c+54!+1?Xvkaj84=MB+%j0dA*-Q0 zAUk8gu+pvj@J0&yp6rGV8U|iUApj(rX;`%SyV*g*Yr}e(IY<5tJ9_(-l&~Xno zvRHeN=*Nb&rL(8G8SgGgLOgjuaLS;$J0mX^ClPu%v!`dEnPBgE&hlgjcIrdoVo9>I zZBH7mhO?F??ZptAM85ItB_>PK1t7_K;7sVcB8fLR(sIvUnWQxm@AJUWh*>3CH^kRd zuDY5_@MKLApC4JQ+GMlP*^fOP_P{37vSe46tmtx87b=LWSz%R36IaSwX~HT=pj|f4 zwi?YJFh#7f_&U?tWLLU>e}-3+XSzTTc)Bi$iNDooSjX$kS?iP7Xi_nm78o2rirIzC zdoPTD-^V?MQRjBo%e)UDy?FGIf@ms;fg-JO^{MqU5@!_>x1`ry#ECZL5` zEZV7cVm2A!J#DmdR9ck%S7JsP0W51+#8|aO+P?$$P?khjYkRt@sS&qOhS=PSsy1Pc z`AB#P(ofogdnKRLR@@U=qyesLrJuAJcSA<%dfG8I;a13y=pc2CwOFvSE6Rq+O8HR) zd16+!$)a!%JV$oQAIfEp&{x5D35k_$E#n8$JYNp49nv$cfY3HB6eowdM|v_ccq^QbyaaUN4ulw{g*Rwi^C8AFW!9%`@@Pe6G~e!;w-QA-d)a%Oe}JwxYA zM_Bn!BP0Uy$mFep5{(k2WNdzV1mPy}MDwy?v?qQwhzIe%f}XYTop~qFB=8p4l7{^t zgV;*jbwz9>;&RHcbZ1$a_ehg?)VusBQLX~zi;}|X_tAOwE9+3kZ!A3bC>|UD&g^LR4qnJ1&s{r?0_-f?<1d6q!TB^2gTJ|1o)D*GC?~BW@Kpc~SNKcp*>5O|5ArEC5f z30rhCr+khmB5v}caZdRcP^`CX+}Ce-+~l=!SsD!&?nE+pOJkD0k&i!+0LzM-9Dk6k zOhp>b@KH{iJp+DRdnba+G-V>M>vMV0Kh$+1X)9TMX<7PX`T zag$@7#XYCE$+41i%HfNf94obQoi%Q9EEbT~EyKwB<0i)zS>iZS=m%5|eU-)Ka5g>A z24`c5z})d9P6;TBV6iewW`VfLvBj30t`|3mkhsaQa!Y!FxXH04mK-;4Gdq_0Ss~V! z@XPSYrmZ{aXBUZ^9INmPx-H~!lVg>ZkS}g>tSZ10HPI0hW7W0aQJAi1jm0by zH#t^o$pqsj$5NqeH*RulnI%*_ZgOn7CFYNt99v;Ag;D9a$+49I9zDdQrgDqyXR%cQ z2^}{%wmQJ`$4!o{u|$f*O^&U#WVp?^ag$>gSp1N<$+0?%k7q4-wk$t-^yyh=$@$|Z z$JV<{f86BQg%)3hn=`h*A%u(RfzJ&45IRLh^=)Laix!j@8Q7Xi)SWrxq3b9QKipf&9uvql`%AIS3yZ0^$+0bG zk&|(gV_QSz#4MMEqoORfEmV$N9-rsBepiOdVa;!M<+c}<(;EXT5OQosad8uW)wtfB z#l>}iSJk6e6_?ejmF(5UWwl;%@hrBhxTMx9BzG5=Bmo&WId)BPG2H#q!*FRK*Pcy~ zKN^l*7b?crFfsZnZgMPLToN9NKQNCq7nc#^t_`!LxTM|O*5YD;xXH1$;=-77{51j- z)HT)~Djgol*vhu&?Agr78dKbR_H5d8)DU)@J&!I*<=J=kJSJ{(Z2vh(>$u6W&a+GF zHVC8cI(rV?0+FNp>^TA1CXcMmT;DW-mbcnqqiyc}}61PMxgMGkD zz%92`m!SnSQSi3D9=uy-uc*u zV|PKDh9j0_Xx!x3h$T@ZZgOliM22?h^!isnMjIxSwM6(5<_nF?Vq=zskLkuuj*VNA zfw;-B35&a6+~im;T+)u49J|GmY3rt?G}Dil;qbB%-hKtv30^B691!=SM}=tdxXH0x ziXWr65+QMuW49PVvw;(UCh|z^sFBcHH#;nHY|;p56^_7^D`1C37N>60#RXK{E$KX{gyHmkANPkF8_+Ej>h)3yJBs^kH6Wj=AE*^jkU=F&u@lo0ztUCZ=Cv zP_&(Ev19rrUgu{R?9;^OEuJi3GfQmp>|%LLzr_138X$?JFb8=`&2=G5r#IN_8d?OF(n(Gn_z7zr>Q5&gR7QOHB9}{UWAcBDTn62*mVDyv^p~)jY)c zOLWCe4usN@(YR#zyTm`{+ND=)d|Ct?d3835@&3N8`CfGXwqaNfS~LgfImb`zr<99;h_;d z_}Z3&q9&><4P69e(yaGbERCtp66>n`IXdVw)G-~?FY$6q!V0^@5>?`~n@y4s!P1W;6e&T zZWQa7eu;nbQCr2Q_KAHfj5MI7-I#uf4XX?n=1w2B+A;kS@3;7NOuxjU)h46#Sa{(J zo`KKveHNEG`kZ3=CCb*2PJs!=WBMhRK1l?BOuuA;lhtU+S%ug595RpTm#i=}JEmW< z($F#Be5NB(r6F>P3PP8xwir65U$Vwf`NY8|iwgHOS!;N9Ouu9*jE+|jmxa-{u;g-1 zm!N@qabU?6U*$a$64Nia(qdsf;Zp$77Ib4)alV*a6w@!c+LSFjVvV7+0dY*l^h>UF z=`wsq@&cEvMw}(<3t6GJ%+W$#z#D7}GDg$CU`i^h@q_ zB~%}}L)zgAg~jws?sH}A-gTAjcLl>@`XxJE8OKmuZCwG$U`)Scw=1Lv(N)#sN~r;L zg?e3~u$X?y1GWt2snQ_*S)a|O>7n>y{`A}IKuo{nfX(*B^h*xfOe>~e@}R{K2*q|x zzvLmC9TL+oIb;b0V)`Wyhj8tfe#z@Y1h{*>fipOss*dTGypeBEipBJ+*y!H9`eOQ3 z@S9tIOux#9`L4%}=~sEx1!j9i3x(QORPL)Y3|~yY%5VC3@XR8#k%;M6`A6$aUI`7& zDs$@tM7hdV{;kE*6}aU>Bd=omRSsQbh*VvA0zzoKm49V1`T-&`jF^6vLl+xqSr39W zW|irU0fx@>U5iJN!bD8J%D=eOWTBExOux!UE^}E_DIU|Wa`JM+v19sG#;-68D{Noo zUmCi&qqdp(O<|cfv&whXYlc4;xb+R1Ysd7f{JxLwL@KLX-ehvQG5sq4Ua*SB^sBsS z^LMamTrj3zWyY2n%!kGFs~omvip2D*9I=Hs`d~03Y^jEu+htITgU9Sp0qV)|A7gT;bpv}5{JzI=uA=~wv=7FWjftL(bcd%c<+@evSFGv_7BdjjuWFZddPiB2YZyT=5#sP( zAIHS>t6F9q+aZ$-Kv(s1Np@rQ>6m_1KabG@Q#7Vu)h{HU&PJgYAt5LLU)2WdBo1UA z)355yF42wYSM?F=pblC5G5xBJSx0q-@5J=0T5TQ185yzFsQOVTQ+335t%Ev~l}9D0 zy2m<*qu%B*{i^=dI)k%f`c?fnl#U_4%sOH-G5T25=Y4bu^jvj=b?j#3WlX=SUszmP zhEzF%x0%%( zu?~g}vlI83HSf0!#bF`ahb%MEG5u;jXc-4}hKlJ|^D=ADDfAe2&$Fy%n>E-(71jNx z5GqRSwN6b*m{;*>tM?@lqPwlbOJ15C)30XOI)vl_uSBt5vdE&f7V{6RgU3KjznVJh zbdkzar;9c7K8AYUQ1g_9N|^1o%3pUu}8ZpSMlK^s7Bpgkzp-)&3|TV#V~U z9WJv}o0xvJ?-canG5uGaa2hGo6rdsXP5_I|NVarG9RU71J;EvH&+2I4*UU zUr0PG2*&hFy}X#D6-$VvULmBo<%#E8GNxbZwN8E~reErHHjjGO^xo@jmNRZ|usQxQ zd!xI;S?fDnmWG4X1W7-ug!9X=dBJWWN7Xa0;Vg~S$*n^ z#gS(e>Ifv&Yuyk?A}WgLvFofY7HKloKjq`lp?T^VACV6Jt(bnPd23Tf>RdkJPNm*q zJ(;&7_p#KdwQI9El6hBO(i|Zu2_4ff_5M(<71J-(EgqhW zB~vL-FLJ1dp{e)t$FB>-^h^DvEg_u|c9XOySTX%l9~5HF!0OUuOuy8ptS9qDtCX{j zq>BjASiNFxuzz%c;++eMe3v?C9cKG0{Tl1cS``%*(=U}2hu8c-{%kS*QU&YeT4{CG z(8m@Qpw@M62)54B!CQ8dINp|fVdZj?LLnJZT+%`(yg0PF!Njv|{?DzG2bB zWBR4uxshkJ`v{k3)QrkN(D-?9>GEmThs@FfF}>9_2i#h4G_}(!@gx>vDG5uC>#~vc2V*0J%#}*+1MPmA`;J!XA zrr*jx`RZN(C|EK5R=({kfLm~5`mKCB(SXezi0QZTPwz$k5>n!i>9^{lAG%Z?)6Y+p zG5sW&yVS6le&Xdmak^*mbxgn2!VrRiGuGTz0!#%SiRpbE2vM*Pces_*n#%7{Gix)m zs6p%GWEako*_!|LNyxJK0NtBUohV=a9({lN7mk>Lg>~J1IZ6gUPFLGezBtX6Jpyyb26i{(gd}Ijm;5cH`7uWrU5u>Ki{__Tm zy4wdB^`Z-ZdBCVIVpJ@^s0%TA;h}U&I7`ISISXLa1eC<$)A+rpFo756M)7cHcru%t z9zzU)xp~A%y*U#7aHJH`UgB>RfKk^#n3YWup#ErfmY$|Y|2EPBkckpOoSa0UjLgU^ zi++TY<3z@}=O`YpMjwgvLvjg`a-%Hz(Flb;*}yYWc#RprxJCaiLNQhLE~X+T5h@yKF3GS3s7xFiC(ndxJMzcvZvLIvjZ$;fUfsZd-T0b9&ZaprQxoSK=om``$M zon*4;rz2;eX=7yZNCC%MO_t%G z6uGIy2o%x(Bu%DL;s--VC8%{|f>J2)4P3v;Tx-B6qQ&CW&RBdW|NS^9QGevAlD`Hu z2pIKgP%Xfy=eV*T;dg}x2Uy9cSrrh72?}1|+gEt4`@yOn8ksG0&rdP0jhe!$`*Y*` zvYqmja5g;#gM;<<{0k%i?n5dM;(rbNI%NkRZ)7lUA1Sm+BFLn-pH$iOeu_%tbqaEO zZVq8~+IxW(JUx1Xd0m2xN)VBG-E^IbTYynSP=HZ9tpKB_1yL1&%K%1w1l5YgTfo!+ zP-04zUQS_rVsV;iigjGFt|pcu8o(%`CTL_1ApyXsP9bFhMiB$~EWjv9u>qrK!a!)Y zpyo_zKe6i;*3JQTkG=WKAYBqyVyhq4U0H^W6HUqjjG}%ufKg|#9&5lTVN0~- zC%`DO>JrY|!WN~tjq|ImY|%2x2Ad+YelL=Ini#;SA&^RlE&-z`S@H;7^LrEkMsdnh zL{WfIobokLiUUTGi=Y_gyfo?w7ch!qc{_kn)XxfHNdrbvPuWBc7&VEkvG^SSO{Hi7 z5q%ASQGdjFuj9YT6)6b|Fp88YvJDtTSry#?Mp0pkY5_)335x6jMggzK;z+*IZW1uc$j}YlSplPr__+Z_8TlY! zl%E#@+4FO&r9wd{V3c2z0ptk*jPeWn0HgeDql<<>d{7y!F;ZcGQHFc2fKlg?BM2B} za-9oclwVr63?m-`7-htZ0!A4Tf%~8o*?>_-W?{f6Bd6=d4I&&c%1AE^7-i(Rc^k}> zrPdH~R*3Z_{4#v95#|7gLrePE#Q~#y)o@#=0Hcgh5HQNm6E!hV5!F^*@Oq{nFv?^v z4j5%*LII<~*a5&OBeWo3lo1O7j517NR5oCgpQoBiZ=?d19)MAP2^%oV&kF&JG9twR zql^r<86VKo1y&Wp0i#U*g#n|CTnJ#4!wdn8GJN%&y|MibRuvT&b07pTDyYTCS%6Us ziCKVA3yDb(B@P(1keme=wUC$v7`2d?ER_RBEhJ|FMlB>}0Y)t(CQIdjQ47ggfKdyH zS%6VS>@0v$VS<3M=ouIQj)202*=*T~(Wk{UF3*;;$Qi(>uwun5ms&aY!?sX;^plN2Qccajp?!h zqs}VrGykr$*G9KM0Y;s*jB^2uI)5dW+vq)et#utNbfp7l&vrh5QD<#JQDs(B`kzOg ztR@XSkL*_IgQ3}r0!D?kSP63<&wU61MlB>+6fkO`OyPi0p*ehjQAK6^fKg$BaGW84 zQAV;TV3ZLl1{h@|!U3ZUKNK*^u!{pm85y-z#V8R9bO12QNEQQ(G7`lBqk=L4z$hca zml7W)6ahvV2_G{67-b~G0HX}|Y=BXrl0LvFBXd^3C@$*4K{+T-xm1WmIAD|(G#fZa z)zJ`D4j$B`5zs0efhkuY3^2;6ge_nJMroPifKgh6JViKQlonYSFp7&U1OjCNMx9mG z0gNK)0ALiIn1`W3=})4TTsnVtz$hW&0!C4B{JFjOGIMbH==99-X}0uXUTglq-wzmN zIO+oq07e<20~lqm>n3=KFf66(bOMiu9Bz$nA!?Fwpm zc(D=jb2(s?!wvzAa`BLD@x&K(=@La$s!wLb6GECWC1sG*90)SD5M{l3FfKi5r zHfmI;>PkZwXdjyO9*dx=e%FtZEC_{$|KGOjh zWr&=jUg}L&TMP>@%24^laR8$X&jpMMqZ43M7@Yv4I9IHB{y)o=oJ?*%4)k0Fv`cV0izt2A22G6sQ{xKo&^}?(E01N95BiuQ^y*>D2qkk zh2%!MvW4L>g3(BB3h)GAlpy;7qb%Vtz$lCDE)vNmiv_b0T;GC_+-wQKn^4o}+n3}P zi;m0+Fv_B0@cn>M7S~!_%rcO?(voliqb!CC809ix&iuV)2^i%v9l$7;MIU(DfKdUi z0*rDQ1~AH{E3hK~M!5_H80AuJNF$cK&Se_FD3`9Wh5#7laumK00Hb`2P{61VnE+sv zD-!}3O*%(J6xe~z$jP7?p;^eepfIYFv^v248_&f6_5-AjBT?eX7-bk5`)TN6LzMNP zZ%PR;D!|a0zH9M1ZNMm#g-Uh+qg)mpsVcxI!|?$|8HSAs^_N#@y11jZnfXnc*6 z9?Rvk@}{Kf&rMeFG+Kz z#0ui_HCzw?qs$6}y5M_b2^i&+rU0WHVgNA8-`MHs- z0gN(ST81pZC}Ic`l@^bwaV$3qNU`cJ!9(Yq4KPYm zMdvOH14j8J6kwE}uJDa)z^Gy}1Q_M#kzNHD72x>*qx^hWf(sbs7qEbL-caIaY8ann zsh_0)qx^KbO_YF9ewJJ)u~+v2M)?K(fKh(F>QFL00*vzWZNMl$&j3b+bIfxs07m&m zT)-%c>i|Y^`htK_Ttb}b`2eHnR_yG6QCy1e>4Jb!mhK>6l#|g0h5Eu`H=oU0TJB_% zM&SZR@!YCLYJ3;~qe2-RFv{U*OWUv{jLre09EN4L&-${=&CSdaU=)`Zy^NkPm8xHA z^>Qd+l$DeCgpmT{m55HKB0jbQJan6%>jxitiC=(2v>5fb`}r;i(P=;11|qt{&vfyI z?)0-Ae216%xeg-H%L3dGRHD25LgHaTC}5PY6P2U|R6&4IT#DP3c)n!-qwM^Cz$lC7 zj@|3+3OeKV2Aks_vp3pI-*~;r=DB0_$2Q9zr#IUS98UQFqpa$?19-2U&l#S#I-HQ9 zxlag~u2csw0E{x7EYB#^5eNXI%t9=Qv>p>+lwpu2W51_-96B@yV3aHF0zxqWMlHlA zP?LAWjD!sfMSxM^9Ln{S#iMa^0HaJchs6P-itspKl;KI3BN}yik_5mghaCbKW%xe8 zD8rC|Q4Yb}ZUHdL;WW?ZCTWumz^E{~+MEF}%CKe4`34k#QHH^-+X9R-9GQg#M7ERG zvv!MV14adM8$>7qj9P%r0i!tI4;W=Kk>M%8C_`1AgaD(0RLUc&|G)xVvYm^qEvwS0 z%v=FR1@$Wl0*oroCH;r2hvI(y3NWg;29j_9qk^IqU{sLl2aF0z*nm-CTo*8kONhl* zHO7ai!~hs&c{U~GIQ+k~C8RS71&lH-OX<<28NjGut+kMRPa>6Db5W&2Qdy9 zW#p(~HpD&vWCD!h@wMMPY{ zs3JlJFsg_^QNSpY4+o6;%3i=JIDk=K#>=CAz$l`H14g|C`AbMi5HRWoE>!|Xxl|1p z#mRhsXaPd$7hF~+c#HjfdC-?3 zAzi{YTu2~6d%6efT6XTN+g`u5zOio8)RkNDt1v&E-91k44&+8~IXpKqvHQf1D>o5y ze0=ms-KL(+b(`{q(cRl^DEH#LEsA8EiUaUxg96o!vXX3rZiie3KYF?1rEK^N1{=tUgUV+5x@%*z9O zB~xJ03%?CcG`@&q)&zlTqVZD0$pP-ho5%0j!W`w@PkAl)sO=~y96kz=QIy$6jw*>i zjoc;ijmT6I@1m?eWSvkXod6UL@NN#aA7oz5UvWhb;dg0C{A2hNBc+Sp35coX-twO# z9nXvr$_(>X&=oFmD}<|+oEOhzr$?E$iY_Wpqd&vnGRo|&{yQYSj2a8(t^F_vi-Xo& za@#U6EW8l~LKCeh;k`I2qE{ko5OO6yiM-`EoM-Nm6%=50iT^t?b5$K+a8=196lqO}Oq0ta5UtWPHb0HWtpr)u zc`H}7SF75FYgK{l3HVH)pSh)XiPEo=St>K3V%~ac8oNUJ0VL@sa__D1aaG)@u*i05 z^k*-_nj$7gWGBslRhNUnr-!({2G=!z09cngscf0h#Uj^ihqBtYf%S68uvCo{_9) z>QY5L%pxfog{CVQTX~1f*C_L?MXu_}EJomxuY&YJ$W#NcDRX3gj72t5H+%)8<@d{M z9#({9kpt0VkWC$sL~7n*)J&LYV|3+z!4^t^ z9|m~8Ra=q9#R#pltJmQoUYa>FoCo^d8e&zHX2vG*m@K-Mc*}7`?;1rfpsUr$hFt+E zjn)yN4q4~N$VEoi(e;MXOkrwvY#I-gSadz9+sI<=9i43~x?vVqvCLQ|K^R1;cbQ(c?2!Xlrw73@?`G-Ruvof^qkW{wKVXr2-wkRx4sfz3 zSfq@~so8{e^!Me!5|=Ig;Cf7R{ErUe>UTfCMLiIyj9e72F8AWA;+2uAMHN_oq8nIw z`86QHqEaxbtIDq~@2G|^x|q?QQb{YNi&zq}lvq?9@#5vBkS&eiGQN~~3A*U0-cb&- z!zJmFmy4}StXbvN;O<%htKv$^m6D~^k#c>J*v3mwMj{>6R6@l%TsJ^>rOs4N^eU+v zwW5-%Ya^GeAbL$H&tJO^gOl2-n|199DtH++1G85&;;x7;b;VNT!u1YRbET=Zq^u(4 zqB^TZEv&3-Oh18&)q-k{6jkPeT1FY+5GcXeI$0s~kEqakw=8785S>wKso${7y}roF zf%`03bAa@c8I%;yiRoy&NH) zqd}^MlJfGUM+(;9wEVY)Jb>Y9#cW!)s~}L9reuapgN4hKCQZx8Z1-;QB+M!Y^$UiKCip# z(I}^5vFB{6rVi*Sj|?uOO7w08g|P!`Ale7oQ2AkA;XaaNte@zlLeU4xK^TOFLCQ#~ z4q76xrbFczsw!;dhD5(mA&13~F?Kz*Y1fMBglITpH%LNU3?t0Q@@0d|DkI#N*$&L3 zS?FPIK5Y@>AlL~aZ_2Xmd!P$9P0VCX6!FnAxucFW*5K_VttXzS6xs}j=I`EpfTiE z*IVlfrj)hnZE&0>tl4&&|AR-j=;luia+Mfl;~@DUlY^A|R~qDnH-Epf(N&I}oX1*I z1LI{b2yTk%>`l=++7zwd%J%Tx7@3GYOuuy#(OA2fHkJOKu2Q2|Ek?1%ovO8_4`~!r zG*zGPj$IhiYIn)N;zbLD8Y{j7xZc8Djg|V0ny2;eu#K*JP`A{M2TZ8|#|0 zPlJcq>JTt~+ZOUczjel~O!oy`Wz0y4VP0tnWCqxt2`3l0lUXend^zN6%uqT@j@q}V zMaMD}sCQN!b?30oXy%?ud0DJB=FUMbP8-yn!$snT;bOWEpm8Suc!}E1Y*aS|m-_9+ z_I(R3QM6doJT4W>bxdsu7O5>k+;p7iNn7>*aLX&Y0=mBPmpcBC-2?ykOYU!eWhgyHeTq^I1df=|H!u%f)tg z1>H0$C!>vFm3@q~S}w_asa)f1b@{TjR&9f6t7A@&W0*q#Lfvcp0hgF>zpcJTcA&%FSK391|tT4P1`4N zf_|~%DYzH8M0t^o4v$aAOO+R~cEL1_FE{2a7L6;k0|*|#ZgR~SlUkj@kyT@AtCfW= zX(x;$MzKY1vL>zE{o*d2jDCv{qa;moc|5#LWybL}3Y8~)q;|Vw@95_p&Wr$Ir$cz2 zGeWEzF=GP1)>TVQ4D-}R?VDeS8+U8mU=b@9Fo0FA0jw4dmc~v^2)TD&Yle~zWw;$+ zZ){n?I?G#g>s_zB^@U>JyTMutxWGkXDZvIsxmn?ntrZOG7dh=qRgqM)%L0BDHZKm; zudvskO(K)Nx09zx4UWCRni?JRg1ynC@yJo`A90_jp4P2iz@XQ-2E7(#NnZm8 zZZ632)R|$WOK!jRbDZ^J!*ijq(hb6hFH)9>eV1kYm)OP+qgC6SOVu3kdue+v;2EQx zorYA}uJE<>ZhOTfX)sGSd(cNPTd2O1qbh#Ebt3>%qV6J`DSy<3imAd0mp3H zy0%}MJZk#t?IoW>tRe;i_NJ>67bS4A6`WUQ8hK&1uWl-0ra@wDULq{7&xRYJxpAXAl z=)P2QR-Hl7OrKEdFhVr<#mfS2tz&CSdd#J3p@x#^L~`O$2{Y<~18 zUdSCe&wN7soIm)Gr7?yYj!sVE6;?D3Uro&ArZ?epfyw#_bO2{&$MU#9hv4m9gme|@ z>ti`oG?zaruI6S(Mn@#)cmd!Wc_TRw9Qxza=6dGHExA#kAuCNIRK8FnvWoP`%oNEC z&*sFn$R^W>C_YMkf^NtI8hjRLLXtDA865vbQ0M0+r)H)_8nUxmW(IiH^Mx6~L0{!& zMha3duJThObE;;z8W~nssN2-&!VuE; zm&dDc@zuiZxOiLnE}q`C89}_u?mO(Y#`l5zNa@`mKYHtPNPnt)AJUH$>VNWj;*=L~ z^*4pv4|+@L;~W0;FJAhMPkOZ<`n$v4t&cy%6;erGE9^S#^`M-n_nGqNK=?@Exi3uo zZM?yof86^hd+tx>FT1k=Z!t$=^|7~m6+>Rx<4?R~_dV&WCcK*;IP4{F|Eza%SBp3K z_!FH^Y}&o;@Zs-m+CA~a6J8BfKeRJHQX|MY`Ec;(W5)@+0<4wW6yh{o}1bR7{r#%jNLL# z28r2u%dx3~Ob*l6TQj5c^qto1EIGkr!x0`=c>5 z73BAAlH`xYA`iuPM;8h5&5C^6qDcH$^x|qI|BPbX3C8i$(aUPIs_RqiPN1&yhH<}QJdudRuZcfsI5#WKa}_>L zW202|GtLp!;>FA=&h3?Gi)tiiJ)_j!6<|H0a=p2lN_xW7fi=mJ&VX}E{Ck4qQRi1n z4jAL{@ni8+bbU?yaQu__|75%~e*gUGc#d0jA@)%8lG^Cy)$#k|_q;cLWMr&m zxKQSVq%l8SX!Ao_n;)g^?Fg@Iqz4`eu1C6vYB_x%Nkc73f#ig<;B#l+! z!k7{+EEB;MzMusZBKEq|<61&$x&!}0y zIr8?Oz4m&q?mlny@%Oywp3@Tt8~@B(y2~p(et2`sweOjqkH5vMiVxk_^2Gf2UgK3q zcSgLW1+P$__sR9*YoZaD;>VFA%HD#e|JIo0Y(6_bI%uCOULeGPeZGTrOc zo!j5DhSC z!n0oY*FTl^%Idx2`?hiA!dne;# z`O{vsdtF8C4_dRs~zj`ANJnJ2eS3Qeus`sH&_q~noVI#5o zVmIW^c&l*cIPvv)Y+;AITML(uzXAq**EK!uXRi5#ck3>7hgGbhcF?>yk+q^UcsA4<^ihE zp$F!@i{iI`!|S{6S+DB$XQOdUj{nU!%zJ)g8)n=(j4nJe&T%$a^XHr<#=^^!b>s}w zC~}(3&zpPT*{gRq zHFSRR_*}kg!Ye%BRos5#kNhce#22fVtc-}~YHgRhu-@QgR}w72>`Z*0h0d7qapL|0;XhhWxG)`#D}f=vv= z4Gs?Y<;^HN!gb&HE7EQ6T{cYu`bSs=TgAOMa8rI2EjZ7+1BS;k*^#iDZ_9DNK=%29 zJ8AuR2nMdtW01DaV~F$XKNHOJK*45j-g~i}PWZa3EOKnqU2ER!y?EDhy8XXv*|B>% ze)!O-y*D>}rqJRIJm59Phq^$EuitxPyxW_7+^eYniud7D`@F}nQTgzxUEUMyIdA_y zZ^u4w@7T46;_pLdZ|l(JcnV%~pZ7&b{TZabg1@)M>$^I~-+_J3KEBPl7xZtj=eYXU z;fDFveR~I>e$xB-AMW#B7Ksl%`0mCpd(YwG^^t;ivL4A@-diHKdncdsZi9~7Bl{qV zLZjzd3@>R&cJAwkny>I;CK5E#j_CnW?x4PbY@sPLpf&D0x zFAjy+@xzn+;FF%6{Oaz^TlxkvW3x?-a_+&GHC`q=zl=J63%@h^8(!w!p%Y&}8p<`~ zZ_VG@034jz1`y$%uiWYb@$+47!YTYFjv2VAsa_n|a{NC{ZoqR^Tr`Z#OpoQp8**EA zT#4Ng*InOF519CNSXCHD9P8JQA8wrAKR({LyL0_|UiTfa=_uQb-{B7NJPwLq(59-# z+x7Jg^sfQ!X4H@3ao!8jx&EGgVM`N3iQ&@^TQGk5bPH*Hq=~e-amU4YwlKpV-D3<1 z0uqh_)QREz1OUE-*TAFa=}oW_9OOZkEn>fAs&~^~YEn#+zKqZOWx2 zBQ^Y9I?4^<-+yC<@XI`_{GA<`*Hkc!=#FB?GyywMh`B3-6pjsj?KcL8x{-095IZ^SdXmeuuE4_50?xiK^#Kt>I(}~7AV(G+= z(~DXYH%Ie}6Fbt6CK}U^B{rr%o~TQIBC)*r$wWo-rxWpx^60x4V5iGF7UaHY0d5<8 z&;oQTS#MS)wy88H=?C?GWi*{w{!*&BrloTvEyv>vz(70(Da_)4Y{WG{A@@ zDqb3GSsL@+6#WE-iEWi~H>E^--X-;NIke|aZ%^Wx=-wr!Q~!MkhU*s6dCs_wtUX z@+jXUGM@qhEmn_7$e%!))l*-3U5$Pg7^j=3iVRarIT>B(2<{P9fiF*>o637+x#-6q z@zP{}qg{89U7RjK&kIJedegWy;soLm`QWrc>OueY!5;RNcME$UJ0!X9NV&X}!?>A# z%v#;pQa)o{rJ+anFlD9skiJ=UWH0pIKjJodHxN72>uEt?+ZAE>=`5K<2n za#D}oj$Y8Hy(Fg|Df}3=KtBtN=WUVb4~q=jzH&N6;`&yL@p{OfAMih~_L>uQe^k<( z*!Zf_=0xKw$^YEBD4n?Oj(9q;_jFln;VF5GP%a-|fc#P=2;f)ce~=($50@ z(EEEudVyS;s?T?%zJHbdivB+xrAnP%jA{62BEF|Q+AfnF<^3|1E-z*ut*FzFP)~I< zc?++lnGbi;e7J-B|1#SNUcy67~8L&t>wR)IAja1DR~55iHhUMBfO= zLUs0p5bXR%(P!nERF#i@x1>{l(+|xP(({a@zlu|Nz3wFcD*X^SS@^U%^!al1c?J4B z-csJ-5-96xsc-fY(awU@N2W1@G1?&c-;sRzl#u-W5UjSf{3bDwN>AfPp=ZX@bBm?t ze#zf%`0!$|zILJK3R&JWQtlojC(7fqC|%wu#C82{yHu3>P9q0>FGzt}iZ{k{YF>*OsQUPtCXu&3Lp|8MiA6BUo76Y-A;dNDmj-%$qtD)q=^W5Ie( zKwjN4oQwRMAg?yw7m4aHvLmAVG2BuAms0)x^L9^>nMHnu>zDY>YP_MxZ-=8nt1CWF z$liJvW1aE=f~)yDB&KW8exm$$BfolQo7zi1ynR@mPw`#R!sS1O{OVP3u^Te^kDNpP z3OEAwYWRRCUY8&35ekag1#ds{tM|uu`tldfq5Qj%U%h93l`sGNIplu|`5%$*qhIdJ zKXwlJE0$o6$oy)5sQQ2Q9P;-fzk2Jv-dBF^9P;0d{OT2W9O&{NRsM_5A^%gzuU@Wy zKKTLB%G5ja&&U3Hkzc*2|GdT@`PJ+E&!_ySkYBynzr)vm`E%&MiUcyrmq^rlq5A)% z%rDjc?$2*Y4@|U9PVS|*b+arpo23))jEtCsXd!qzY#3+U3^EAeJa@8p25%&>Oa@Of z@m3?foSDhWcUI_|xuY2#;Ua^GKf?ulOr*ZlqQ8YK8$I5a9nK>#ixYDN0gtSRKU}8_ zVug4z`Edkb$w4AC3`_BNCX=&scpy7>EIZ1IM*Nt|j*ZM9IFyjUhh|d@G3mOpg^8Kb zZVJfIf^RaKPZqL*#L}aqUHn6&p4selo@8Y>N8Y&Z?D19}g(y8YH++)evggPxcqGjF zvxQFjoUn5SFSrCO3_1+zXXeKz_TqJD);?Sqo^0bmmZ77CV$HVa zvXi5EHZX(e*^?*<*?HYrnqrH{(jkn%VpBO94qmgCIiyh?-a1hinT?v;kGAASsH%dP z=3;`{J~=ZiyN4RZFL@nUN4_7mmn9ZvGU9tJE2~j>&~)QqKAUF2g)d2Jga!%l*2U|6?i7M{F>=8k8so|j-4)U_q0Ci@k#|sl6 zAqE(#AT7aI4B8;43d+?Tj`9Rmm|7NN43g-V{GnW7Vqkb2twI%a{xnIDIf&`wR?m`h z85k(o9>Gx~vX@gHL)`Y^k%^Z1xj7iO=$&-Fbr|oHPV>qhpC;eKry&p1 z>lSPkqdS+zA8ujf=)l}CCLC!IdRu1aDHbv2;@AvPwfV~#j43HSEV(3JI`@;X*8#k} z=o@Y0IC!54W!i<&@NAOFh4gf1_GWSo#*fH!4uFF8C($O35qX6Df&trQwjJ2`4S%oQKin$qB*n7@9)pYeK_ z8emPJdh+g0kI+{=hlUIA7SKr@X8VFXdHa^(+2JF(Nh~|C6Y3|UiqAi3mK16m9!?vg z)h!cQMAw4)5NE^toyJj&NLo2=X(`<0`eY7rx54cOy`@$#vrx#6L1&8cganG`4pNlE z4PKO?J-e3ROAh$~D%kiPZltQ3ut(Y_m_@{ITikehXV4{u-0)M6B zsNu@^;Pm2k32r1--^1zx?nL!_*zQIz2t6YsbO{RX+J(Zpt#|n@APe0=0QEyUq%@t#- zFS+w_XFGE6Ju2TmJiOWmwx&zD?-I_LhoAAJF2#`^+laEHh%eZEbNFws%|w?@8mh z%(%3QP=a)SMeQ)Uu)Pbe`f8e*U6Wq=P&vwMSI+8S*{`~vX$=)LHhXkDGmV|7&+^PN zDc3=|vk+N?2^A)Ce4Ip&Q!Du{6ZLSWdQr7}jP`YRsL>hV@k7!5!C5S(r6{O1J2E*; zTXNxhQ5>&MkgOL6h`=1>R)7kuB#%uw=H8UJ^+x$Z zhjO53k?SJmU7?<8dQ|lA_5yJyM?=$*NAB$07&h3{FuBPy-pcjmsGadkBu+g;GYTsu zK4H{VHns|({*#EDJB1Q)`&BqerSQJu?iF53_9PjCt}q`t+e}4Ikc=LFOUByuka~Mx zHamIYsjC(#w}VR@TOC7bzd z`FQ0{v__H=3Q;LE`Up;N+9_nJt3qs0#Jm(;!Ig?;>k2s*OLr8|Y2E&jN?V1s+4n2r zxBap)&Z&&9t5eoVUR|?QCX16JhANmgQVm2;iUL(rti_a{=oR=m3PR9}eh6kc$SC42 z&0yhM>2!po=5abTKb;=exAMM<*)z^Qvaxm#;v_+|vu!#*KbPg>Oq=nMob&@U{dBM6 z<}6RINcSQqYX|U|UOa_u%T2DYCYWH_rulJNz#E#*;x?xG3LPq)o2~(01F4pLlMtGZ zZwRy_(B8qw+5_UNs%_WPgXIH9Z~PRF=B;x>5~`N>9dGkNY>sFrrMFYM zN2ME48z9=cP&0jXH-`hkTP(L%oKEDv#<~@8s;tb5T+p%M+$7Zxix!{+hj7nkR!EXDd3f_Jr$}>!pZ}5A5$yf=NrrIg*aPF(UEOds^3u&v8=YEYvrcWX z`rh)@O4l~EXOms(?i`fVcCBs)jct#0cn6CZIogWT*9pFI@dGa$g7F(4VJ%dum{Zg; zL9?yX^5Zn_dipujQ5$@i*R!?pZgtF5C>+tfiUx!>7IZ!w{q)_fXo7tLu8yBg9mNJB zIL5McncOLeAs_hcHhEMPrV&An|&XylXa{*!4KEv=$6Eu+L z6&+$~b7)vjD^YPvKkv*A09Iz{7Ck$vH;1A=#sr;`_yS1dWbcmn*qc)`G9#-vV;@GR zF>7ui!cpU%fi#6l@yc>V!VA!m4a|mjkJwHOPS4?)4z{0j;(m?u`JCfVH}H&#JUw#r z&9AU3yA8U|x-OukxlQX+X{sHyU9Lh9=)}fK93g4{rf>6|3D5gP9}r8|XNE~UfgvHW z0P=>Z`+U_^FP;mT^VvS!O3vX> zuRzC?G*|gi?ui0X4vGh3gB&fD4d5Yb4)a+#Z<6SonK?Q?t8U_PTRq3`LmdB)DxsQU zJ4SbZY20>Wg+huQn9t(5H13k;DUrrCiosSUo6L;zaG4!JPd0cT% ze{5_PM;e8(5J{MhI&3ReEvW4r&WocvRTbW^mKpgfJTp0}&?;DlHiW%xvSw{3vLiIE zC{zuqm}oC6*OGRaatGl}WbP3d4pQotkB{-2>R;<3TDT?=y^N z^K$f!4?`$;Vq`M;c#z=1FNQUl@eoJ1n`5#-&+wd&_{k%f{jj%qI{3A^|ppvhaq!RYM zNZ%Qe)A}vn#or|VLYGR;Xwslc<|Rq!QdflTMnA}_l9%gx3<{q0TS}{9BJ6-lPH9E` zDyhn#5)YhFSE?A~RY_AKA=$Y{jd=u zlxh0;j3KGy*EQ)zmHeS5^{Qk_5BH5KX*!HPDRF-2+ZX!j*17srvPY7HfvKw_Mo=YB zNm7*ELog`LPf-7XF#QM41oa;X(Ld@a$3;;8P?-Lq5dA|T`X~JQDsRXv2Dsf0+Ws;CZ&upyOvqpsaeDyiy2x`sk( zH>7IUryGBhN~$V~yy{BT66LDo|1x=1QuV3GtFBbbBJ3uAv#ytf3Hdk58UwC8DAN>> zIWFs>iVV~9E?Gue%91}*@~VnN^Vd=3Q+3rDHfy8k#-O5rUHTP; zwf14zj33Is5jLPSzgZ8Q`f@-wS>^gqNg>TDZR$Aa*F<7UtLn-K3oMbU-tU*%Jr)lR z_cN0DO{)qrssB79Q%VMn(>$3_)p@rb?O;)=f;Y=NSb$V=T$2vGN+w^UNxdrhI!!vD zlIr6i=#otR=a5X@EdPcVr^RLB8Tt47@-LjBN`A5UKvqhYn$;-lVM+R^&K0PkA`o;g z{h(h}@jq`VvbrRcT%bik)OBqzgEh9LHYSRLQqX zk`VMaCRoCOuo4c0lyD%dgka-?B@Bg?Fceb4P*@4UUbs5;uIJH zC1aEqslH#i%J34&h_HT@yjzkymOoLnK;`2WGjH$v#HWpC6iq3BPJgjqlb<_(Q~nL{ zbj@ppy5sV1gdKjJOuku@dR6jCO*;Hpnf$RK{X!?rO!k86{;AqM9jPklysT24P};LTV=mY zNJ&b>Oy@vJZ#%@DKg+vp_g$m3)^b1-zL8gZPvLp+GK`ymyuG zAt*~F{~t*bOP#vmC(YCyZpewDmIlloNhk2R@iZ9l7Pdq5>s6(j7RN~-!% zZ4aDLSD(|hJ*bkZenL=PsVYLFN~$ViW1^C#wg>&jsrpt`5qC~1sj7&XtdgpJREZ&7 z+cw=9gDR;iBLvmeO-4{9CnZS;sw-1rwg1=k{($UOWdW8koYcM6uli?)E-`F0gT)0# zvsCJ=(z<(9(iC@Nu(%tQ?w9Kt+^CXo(xhIMGz|{iNvZ~`VWFv}(*LDxtWWi^8gmlU zohB1^%j2^%`WUTGB?-)&elU?#k`QtQsZS+WOA?J%-x+l^t_Ay5a>5Z*S9cgemAumt zR9DAKRMCL}`43fht*dvBOx|cnZBl6E3#yA{vQW~f((5FR3#yADOHid% z&AFhun6U&^S`7ggG|dtz)wqaNXJrjnTQrqEplMCIy|-#w;~6#Xs^-)*H4>`(X)#l2 zRk<)DS9NWc2{;IqoRB18zUoTdUqDbLKi~+et0#;`l~e~WLZiC+xe-)J1t2B_)z$Wh zkVMfcdA}qHL8&P4XSXilfJ&<7P{spi)Rh8G!D^tAsyRYXT|H(rs-$X;5L8#HMbM~{ zsyRYXU2WElJD`$wBha;2&$xNju2E=pEiOjshT4M)s<=y zmO+(N%@Km?>T2D%A(gZn7rZ|WHtuj(;|_;3?r>P+4xb4&?r>P+4(roF)gs)UsibNS zHSX{kb){MaL6x){cQ~-HNdLixWh-f}s`QAaHR`rKsA)}SR9ZEM=Cn$G(~?tZHB=<0 z(lc^2s9cpkrfH35RQlDL)^tXt-=JxYXH;6XHf#gEN7m_P`4_jXZ;{Cd4Cym6`LBi) zmj$hrf01#QOb!^*jWRiHNUHXKWJs!_Z!siUkp82_qG?UKua!xVoT};u zsh;{l8Heec;08mTc)u*{ zZ{%O}u}c1%CLL5&GQ|h>#dil3^(jRUNfynSzBB6TF|EE&C7*Hx|G(CCo^-a1#%u&wh%cWE>I7pQ~L`j7a6Yz*p^_0ZAn(x_JD7NZAn(x_JD7NZAn(ZPO5H!>}X?L zlB%?utgy{&Z%fmGDAlMH{Bg;*!mcDM>`Ji0t|Tk$O0dGNBrEJnu)?k+D`3CZv%;<< zE9^?J!mcDM_ygD}9k>5(bO^r2%98544QN!V zyEKS{UCzX73G83533~LAQj*jM4F9xn+G9bt>#8s(O50ty)~RuXBXW>b-(omzm+JKf zl$NShVY{eMG+5i?Du8`lgNg=xNFR|Hr226K+9}n;8pP(4vribr?NYU4*-oj-pv<&# zCc`pTB{Uav@KxI;s(s8z+#yv_hC8sF{fuT;v{c6oNNR>kp8gotw@&b@RG%~;*$p&Q@6nek z1|==kPiWA2!EGB4pSdd4xhi$VZCFYFq=pOE_;tfuR|NlPIZExYma>K(Y_aCDn5b)tFSzbHvHn>nx&FCHE)m^))T@ z@ANUjjo;Rne#!72m8ytMFmRl4l7Thj;1yQ5RNtUM$y%rM)gDVI)wTaQg#DWBJFG;h z-q}#1U`cL+fu$;h7tp-=G854_@k3g2?r$3T0?~jV5J@==Nwm23;rYgw+of7EpdC^z zYf!QiWP&nn2&G|0C5geE24z&LGSFi;c+~@PVn=;%8B|!UH>|wztXs<+(MOnCs`Cak zDpj#QH%`ueXc49Q_Xf0GsxKIjr>7_(?m>o=>K%q^hg3x@DY5MVITOj)h>)sC20N)* zB|J;~mX`Ecef%FmE!gn72lSaaEa=+j^by@yst;?>8NrOM`3Jl%RTbD-s?u#S2bJn2 z7E9OuI~_J^Wv|!AL4Ew7KFWiK2X$C#usPJDAJ!Q1AmN1Y)5krAgIkd~+YMTt%md^J zHy1kyWJ329ePKx-WmXr*m+vZ^rN2iY@5BA6ey^>(ANYIM@IIuxZ}_M_m-qknYJ7R0 z?*V--@8^9~pUeAlFMl)hllR}gSD(xKXrI*Q@_yTU1izc<3i>GTe|=b=%ll|M^|`#? z^#y%y-q)&kW8?PtjNWkiygojvkFpmg8)5x=iz~h>CA(s>-xcTob4~XOy|0|oN7-+d zy=8d{B2F(4kldl^rC=VW-)aP+|w`lmJ zKFZ?*@)SZG|Nm&bztqPc>EpBdC=Ue$dgnh*f3}97uaB~|FHZ=>@nt($>?<4gvO6Eg zKdJkjtX_=k`J*hT#PQ|cSQZnzG`-yV#_`{-uS@@q&l}_TM>YOu_3?B1_(gqO)W^s5 zF;4%ChW}I_|3M#Ls)K)6x0gQWPGvzKe~p5$+cb$ zmyNaS^||~AAdY{!&$}k^OG+?(3;w_KGQMlqMjzTM7V+UDr|i{dZ9yt%uVcGejdK=` z+>AR=>%f1aVuRd`vkURx;vB&lS(PZ-+g9PPWv`7G{28ER(MC8lZJ2L@a~`nok{IoSkflJo(NvMQ=UK;!H}6RO_>4y_zmt9}8Hjt1?*FB9o?4Z*yj z>H-7+RY-~UHu`PX8#ROvT{*mUSVN!^a0t^aT@!eVn=Z-mAZyDi}AmGz$ zFX~!X#p0Z)aA;<6zK8c6s6g>^w!(3vMUcO*)jU_>d>i3il}qL*-%B}9;XFYiy+Yp- zrg8!Px3|5Ig!zRGgK`f3x3|&cSOW;C%lR7g%Q$auJ0)P}_$E#hwEhTMRGDDNL(ZtafE972&47G=&=nYH@qpRRUH=YAcm{ zQCU=F3ZEwp4)`d_=W!S}R5H_Nrb2ZYTFE#k77)f?c1c|%2Gk}V=@hrto54+3(^P_45hs0r0kgCkTY z0O`if8~dUwk?MyAN2p!|WWiANB~rZ&;l?;ZwI7i2CRCp>I70O#Al)g^FxiHy5dMrK zRK0*y4Ao$whWiYTP#pne$!M5N^&NvFRJ5|SXk=|jl+|x=gz6w5!5V4T^@&s`4USNy zkbfzv?5MXHkXxV=LnOB_4)w1afPJaM{dDCPV!8v;$xd(*WKsUNMWSvFIMibhG#Upg z=^{A44V*M!jrg1Z&Ny%y@%dZe>~6y6l^8aQP55jA&YmWGejPaboACKl;MAJ%IR%_M zoA9{|gVTHyJ~spBP!m2M2M*0X8`=3G;2def=R3f;w+Wwr2F|f2d@jP8($OY-ZU)Z7 zP59gooa0USs4xFC;nR)~KGB3vA8?*%!lwY7$D8o^J>WdmgwJ0A=ete#oR2BqGfnsm z0cWWRpAQ1(R1-d52hPu$@OcBKlP@;l(^a*zT*?IPZJ)qjx5&KZ1%NqLFLn`dCi510 ztmjOex3^u0zet6#LNj5S|3Y=(+;>4+@NS!cG%n4AY5vPI;Zg6pLPN6ZMg=YbpA;zk znI+9~$%Z`3?Ep>+XKtZcF3oLumiu*_b+`yPqggJ^ZAn6V+c*8j15Wd?aquB!+uM9y z01jr+Ac}jE(B9UMzaY{@YDWkMeYFwJ*MUP{9&3d2@4)G3B5M;Goo<425IBdL;5-7H z4mhHbK0hE?O>kZT1}B@~Yz5AtCOCHihrVppNS{9=K230522Mv4oVUW&^cAZ{vhDy5 zeW|Ju4&4FKeGlX8M^sQRvPI_ev<1ZT`KfGHe@xwC1;GzV7G^4H1_Io8sdQa;?S}Q& zDmfH$6t6+>kDy8mm4dY67BdY5j%N(y;3$RY@X4i2p@jL5LzMzm3RkJ$x0`z_)`w#L z+kk^0QvCUkD~nM5dn?yA3P<13uZEhOqbUElMRHUMIGm$8fq(%&Rwzg9g)`t*=zQ~y zNq7B}qb`A}a4T?rgfqX;-8$W)^WFL41 z^WG&D8>EjfNBo|`C5QwL`Q0tzce09#s02PlLH_#cSH)ldKOJ8^ARO{n8*(Q5>(j}c z$UeBjzDR+}MYg<7Yhx1A$F!WZ|MF$6VA+5=tb++ z()e05f{X2pyAoerC3^rk71T)CxSc5$sN4*kc^n(zydOC91yg&!^HD(hLB;(YmEiXQ zNudK;$QJ=wz!epBCMVd~cnVs>Sdk*JL4Id_A{TX4Vxu4D92;~;>lT@}Tn!0yvAr$j zBH&DN!XR)sC;0OgnIkO#U$vsG12xjjEfj|j;mH}!8~=1w5WLkzz!}BiF^s1ihd=O{ z0EhC%tI>sFIOt3(sR;#?3%JrOZwx~g$LjwEw$F-UwGAs39IF@l2oO!Nx`>8z+w12I zT1z6!w6{Hizhq5YB%VJ62^`P0;tb+B8q0+JO*DEDZKoJZ${U39SHPkBG#iJ{0@4rZ ztRZC*+Yo>;TJ6t;nIPDVI_1W8h8#rhH4s#Sm%*okEWw;5kFh?~t}g(`4YQTR>LN%v zR>?|kkyxeOCyv$n?yvf)wDTg!8CS&=!I3qXpLxR;ACy}Cc-gG5kb#V|(rNzzFqqAYcC6eYlO@ksV{#39hv*`B@}30p}zbL2tr^%pT7YP0PzCo zNr0R6z6dL3+?O}TrKof2%S&)5`?P*v?gj!yX?xo-{H3V1Mf&m| zKn3p0S^7#QzKCgiv-F*L)tiWqrI*@D`p!wycZAv=IW`8A-|NPPio=0TMAaB)_@-2I zoK0k#dVFw6#m|@X5qFwr=(HO z@8Z)%=)^wdPpa<87x5*I8ROVr!p$`MG*x%L@jBqp{i&NpZ6vJrG;A#r+!2PDN*2wb z6`VyAGJxLKn+FbOQOdNwcPIngGbJAULYcZuvl`PqVtL*7dn4|d}sxxy_p zt9;OSklt$u#<4=Zdxz=WYhqXVl)Rj3;AO(18U9nIcW(y7wWCDBb5MaJp)!-7&6TgI z(${xQAOu&z%l%M;yqwg#N!D9{v!Ek^A`jy&AkRo&#%BfaN#1;R=2-(FoZUo)famxj z$Q&R`4$cPv8AnSvp2^ElR~LX)`4Vs{O>q7%a1J%Vkvzt&pgi^`FjuFRz=xGYuW5yv zLpp2%nP;ZZ6mD1YjJ^#Wh%Hb06u`uf-VWf6I6PmmYKRRSo^AYuhPYTP2lu0*59E zwttNSLi=_klWkQ7B!&BT3pqd#2j@2dIc4}rPhsiQ3i=6s>vwh}T1jtP@XRiexqudO zgr~fQN@Sh@4o7$=aA?f7MS5H}B(Qhf)hWTGv0&YW?fTAc?!7@UBA3ijjpnbG=)Hi= zXs&XFqW8KvZD(IkG#Q#QdNLjQ43Ue0q+eNG>i~b4*1&-ApLNflv3dQOlrzBQC5WC8!6sz;g zh}9QNtad{X!Xi>6R%vuFu{w=sh$68nv5`h!CQXxK)sGGGnpXTRBsfP6Z8 zM11I)=ata`2Z0)ucuAv-TLu(Q~30(fjg zV)7RBEn8M%!+wx~RkEGsSw3S!!t@K-aOeGE!*w|G{XsU|vu!4_HWTRoI_-=t!ISx~a_93J_l-X3Qrj#9n;5I-GIgsB1WXXX%Kvb`h zd`Nsw0CLKKd>4>z^jw>1{~nM92lB6gEIE+XkTZ|`<7Qgho9Ks{?!YI#sUKQ2i-Zmn z38b@IB-7IV1!vlXY^?A8Iv|K*1Wy~{FH&KwP(*zgKN#h;+^^jf1p8tboN1>`L{YBv z3uW5(BTsXt-9~Ep1(dYj(k#>VLt)Oe6>#+n_3m$)$h-s`eKg9n*RPRGTYs%!sX_FT zWV(yI5|bsK70_J-hTBMyEb%GeahAXW48Bs*(`{3&e6*w+I;&{$)eYq1Dh9{wATWeH zh=#_>>5ixkXaz?U#f)2I?7j;)98t=TE)vctqPG29BI*<%J}=5q*WhlVS)Lzn5-k)7 zKgQIX$J`oZ`KF~DMU5is)q7%ryiD^k_A-s{L}ZJ2`B8w`%afUXd3#-I)b>rkkhXUL z?9a2Q?e8&dccV%8P`hqHXXSRC0N8Dpj63}*qNrVKh148RS8OPT(1)HJZq#$B$KAI^ zdfd;A9?=TfnRXS~&XlzPh!nB&69BWF`8zdhZD%t5V&1ep!a!F~XWPlAW#iLNBHEJU zdD{5&64zOx9@?~MY?uPnMI=`*Bih<`#_!|EjMNA3PD%ceUqaE9 zNP(Os<1ara5GMI+#~Sh1**NokO8w&SrP43l8G%S6pY}KKDdADy*#PopIf`BoX#5^~ za%K=;N2bSF4lTp)j6=EQKi}{DXj?PCF94^R-*1=@zh70??@z&BJnq!@JKgIw%5~)T z_g*G`KMQBce!u_H=6)YvhTr!z^1J>$(Sqbdb4TBgsDWx2`Q#qW%qoMf0zD7exqcDS zk&p?8A?uES#DVnEE`tNBm}ZkdD5S1N&12(eYYpQ)06&~Cw-|U z=|?>2W1jSjJ?Zp|9XIBmZAtnePx?kr`k9{ePk7Q#wIuy+PdbgeuHRooE_5J$hpcq{ zi{1B`5w={SUw7hD^7t&aom~xLW)-}S#)MSez2jSe(=9ka4}x2X3U}G=dIIyIQJ7wt zLYmp)&%UrgflMAPUgigvc#+xHAglosK~^e`VxAv+5I8Uha60kVpUu#0`F#({DEube z{lpE|u88Lxu^3Vq;+$v603T z0z7-~2Nw`Uip0hro7nJI81|Gh`0jELJdgjJqb6&6W=mMGyBf?GB6n?vRQ!pHLayJ3?-d5?Bn@|aeA%JGS6(Fvzfsf4I9j0AB5#~+x0B2 zX04&6Z-n*^PTvw@!?oDGVzCuTzt@vK;z_4x^)q9R7{WG5Q zV=YO)%ab1QX+6L9-C?Ec@iYSn=R-f{C7zFqhDmX#f7)fDB?)Kw@!VS!izPi*sblP@ z*ttH=`p3jRZGPVH+O?vns|jaw*LJb!Baq%_q*n^0uWBtXcP?Vp6-lpn(pP)ZpZ27W zd(szMl3w(rpW{jYt|xualm2*1()W1M&-A1};YsiFq@Qd_dd`#nqQt6rx%V+o`lX)q zr&^Le?n!^%lYYXJ{#sA^QcKczd(waANq^Xr{vyUxH_t!YlJs4k^k+Qj4|>v{^`xI_ zN&1*4{b^77QBV4}Jn1jABt7j(|E?$fh$sC~PdeQSfRNUj;u*Wa_&(xEf5MY~*pq(L zlfJ4Y>6<<2k9pGX_N3E?+})__Xi55@C;fyc{Z3DM)suc!9vL)#oJn2V0=|xZa)t>b3mZbN3(vNu3bDnhiY>?ab4J}FU z_M{*7r0@2mpXEvKZ%O*qp7gst>0_RBdLqbe`{tIUU+GD|(~~~pNq^dto^DBcrzib( zPx_!I{V`Aau9l>yJn1!0`bJOsgI2np&(n9W>doin9@g@ad)SC9Jv$wjRzQn*@kWp& zoaN8?)%LlHp9c4^R%f|~jp(e~{%Z}|E_43>!glrkO#D^ZCPB{JJw69^^bnD`!AQ`3X2L zX)1=Cji=kjP$g{{@+v^YgAC~bgbJN8q#qF48zsFMvK5d)R4t#I0g-tx<5U5W`8-4Z zCm_2GRfylx&=Y06zLCgK44%cpb=&s8 z1dfcbO!Xr`WW;C4FNibjLu;`Nc_o&~U5i~#3+E^-i)wEp2o~!sWT(a<9?Yi*2(O%^ zG~`x=lZsG%6cCCX%jb^(aa-{fKqQmsmgcb64=QeHhzHF>^ds_vwb=JTm4+hLV*dz; ztdp>YF9Cu^L@d^UCl)ErtWVbf;_A}_2o)=9BOnz=)&$|eq}Hmp0dg3@V>urNMCJf! z7d;qvs{7omPwk^2o)}eo+SGq!Ur^2V^tE*~p})Cr&tgJ`0Gl>6eS@j!iSk2$vOcH;mjXgr-TM8_ zfGnriI93b;fEA9d0c0jD1{{Rq* zdE#+KP|b4y9YWh|{QNm^sMx&vBp{C&eV}u#jDd%rOA(!)2hN?2EP5vd39@`v1M;xp zLo#{+IqXnv0;J|ZwgMt|*|>mG0EA`)mh<}oIpR=#g!nkJ?gQi;gQG@0#8^N0uy;Zl z2y_MjP}wL59tG9U96nD2LQnYHXn770cYLR9Ls<=Doi6|+t+}d^s1Ro2k=X;B=N(yZ z1Ed3%1rYkESqiAA*ofK=9O7iHu@4aPvc>r|KuBMU^I<@EuU|ZP4367}17x+KQg+T_E&&{?&#Dx+-HwB=0%VnGDUgF}0J+%kAxJ+U z8y!d*5b76p{F(yfY6oXOAd5lNUxxrW1RU$ZPXofwU63^{281Q~`$)6XFb$TC4sX z5V>Dw4bQ(6?>}sd%6cOpR_AcGq-M30qiseS29B&1FrN%jp=xDS0I@MYhlliP@vu`ba=VTzgo#10^*PCVfJhR7_-WXW^l# zK{*MUNx-GsDIXUNLd*2CvY54wvi3fvZXM=i^qg&ok!q$~3Yrq~8z(ZAN?1EkK}#W` zbJy^uO=A8AezZP{`QD9$sK1qq)mv^l4<1BwIdnJ*!VquQgWgkxnOeRYMuE9}46If! zI>Vc`tbga0;i1x8c-;+!Qf{D_nVA_%zbhNmzv5B$^bYOM<}0;AxinDBXR1SUQR;-N zK8K!n+NVA z2L(ssXpai=NK+c)CUNgG+=uql+xDXTsULYFmO+pt$7;5cq!lrtE()oVo?WOx4cUn2yMLsA}Bze>5N!=5*OuC4?q^uudn{?Sw+klOa z3O4*2;3V-`S&BD`Mx?BaLp>cDWd3?W8;~SPv57Njv`92y6Otq;%NYcc8nhg`BzacF zI-^IEhSj4=lC`3-AgPfnVvwN0X~_Ob<~SW}BX_4R32)OG8!ISoAxTRi1(s#u=L6vJGtT%EyEgoR`k#9Oi$7~8r%92p)R!^$wN zj}$V+!a=OZg!IrmBE5-aY=8NE1&C}gNI5jhw zDHLa``QRO+;Xt`Wd-vP(*>W{U0CRtz07{p!=!JJ}Qp5C`4mC7#s+OGMjnvzRAr^tK zGQku%2+ZZf3UdswHtwE_viWLN2~bO>;dFkwj9(;I9?(vs`w(r<7Hhkkym>wP4F}O9{J~Xm*fITv_ zWe{G8w8K#)*uV}^2Gys>K-{)Ba=PH7YwkBaBDa^v^i9E zkhkf<;Cw}`sO9xL_EbyvVDSen?e6Uk^3$`S;;3qB&U@E+At#A2`Wwc;t_5oFRY$&+I47E!(I|nOGDmB4-rKZh#&mjm#>!c z#cS7w8MKl;Lg|jzpwWH6buf}HnG3H>bA5ZQxU+!e>P&G*=~g&Az%Blc5_gZBNo+S1 zib!JMMoLhKVQChu=}`^U7}e+NEQ139E8Jmdy$ffLWM*nZDo;`99KeF?^cZr`rWr`e zQ!TK)wOGSD<;&q@xtb+DNXL~Km8-OHz_2JCX0eu-$wE!UdLcWb8b5=9AuLallG%Nf z*{89bPF7*=(`qRzEX)uCKnvxGkYWH;mlE-uucF5((#+m+6<=+bm{DqnbI9((xL3WL3BXV&e%4auO5IJ%&-t+7-pttrVyjptFS1% zRcd{LEG!;rlzzn)rSnyjVe}N?J#k* z4ohurXj()5(m`i7E5x{!i1H+AB%hh{{AuhpR>GL;(UIeLymCg;2!V&s@A(X2=Xdh%wF3clGH z%*7g{kl{^ZdRu=v84oI9JdrpUqu~HbsT?PkBBSX2;V_K$r4V6~OUjktKoQ9d5VzK2 zW)p8Nn=PWlVu(=NT;iXsCQ4GvdOK+&ki#RI)q8hUr5lySSp3vcB=Nh_D?7F$V zL7QQqBPcObGeCsav^%Sy;Fej1 zLW@oSk|SSyMqY^ArC0&%9t5v?h%AAse@E^&m B68-=H literal 0 HcmV?d00001 diff --git a/richNpe/richNPE64.dll b/richNpe/richNPE64.dll new file mode 100644 index 0000000000000000000000000000000000000000..e8cd7e530b87e54c5894b38fc27728e513f58b9a GIT binary patch literal 421206 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%0Ad-))s_bO}nyvb-DF#gx-eqeSvwURe;sQ zZE07wiLSAZL}+{3l^vaR)`?tMbX?hj`I)s6p^W3op2_vr6$p)TT-oBd(Ru)(e8-ht ziS^c>5h`?C*+#g<`UIhIjw`GFw^;?>L-{$bEYaU-9g9$zPnF_d#p_RVY8ll@-^At!W5# zJFYB`ZnBmlG~l?hkolPPV}w>Yt}Hx0ZrzX2YR8p@!Y8cP5W3KDWm#{twfh+;KgX4Y zxZhf32(5EmSvdQh)r`=3$CYKSr>!*zZE##!l6uD4h|osImBpiHt!EJ0q~^j4Rcqq4sN&h`98{Tm@Bi>Ppt6>l?`)ca`~k-7on-cj5H^MW7*Rk ziAh2}e+(zH9TN{Hb0`91xe~^+DMCv0+wWvvL84(~ax(7$$;r&nDLFd{Qi8II6kY)2 zTt!i23hiXBAcY5PIdh3n?j?m>oX04NtoVtKUc-_cKTRISa()x=K;lQFkc+dOfTElo zv^~LS*JdU7>{{$U_}*TBLZyqr8);)f7&WLaF66kCSO9nXH^Q2^kq$jlT;y zVbT#-GlH`w1>mK<0}&#WQz%7Y769-#Dbxq&Q;Op0@D)T9axN8#-A;aLfODyUqK?Hl znURPUIL@IInTmv;A9qQ9-j7&^T-KsC-VpB+R6Ng zoRrLYnd0*u8K1vp6yD7py$Kr$->XKf)7Qf)nLen1|=aV{5vV6uH7d{0CRU1oRE z7RaqWxbQl(0iIIL!#Q6JL)|QKGV{s9ta2t8=E+t zgevEeF&@f!P18BEjM23m3nandd^67D$@v<2cwCjU&=?Qp%+hquOJj5`=M>Gu*=n4} zle30AJi5v`Y>bC;?$&h9YGZUQ=NZkzxo(`tlk*?)upMy*9OI#!0z?a)bK)3X%Q;f> zaHbsR@#K7)JY3)7{5i%$IcI7*XVfvemh&^s!+Ca`$CL8}d3eH=v+o!W<@`g_IUkSF zwVd5R5)97L<2;_6!^y+LuAIBacqpe{(>a@u(Y2f&&BHlS+Pv~jK#gn0bUghKK_6DBSpBr$1eM`=c`E+jH~Vq3^alOPKZ zfoX||Jzq0%Jt7g!GeUQ3MlMw(GJ0ZPA|ovXS22h8M(ZZ$mof^pNzCFT=_|2q}W$A6BmS% zn6%h5=z_+zqC`ed?BQgjvEedO5+lVPubH^Il*FXPo~{|W@RZ2tiM@f0v^`vtN@Aqg zr!^Cos*;$r*pD?MSFsWqJ+b?NUdY9*BqoZiBm>vGk{GnOHZpM;ERo3*^&`+_?8{XK z#VFPxJc8Lk9*#-4ZWaQQJ84elS(0gGxR5rO{4vS223%PiOx_c*(rUTXHke#OGFz9d zy#*%Bla13xUMomU-9<8MD_7?RgRdc(wTjDigUPp(%+lxj-C*+X5L=kWQd^9qN4M{i zeqaKfxiYLpFa>=HU`!oX4xe zwdA4BxbPU`VPomlbS_24=vvOjnuiONaUM_3{p6wUxojEZp`4dAoeP;Ux|Z{)=Hc>Y zoX3+h79^?iT=b0bP)>!Wa~U*7*K(RQ4;M${Jf56$$iuq8CDRxW<=m?2Ttto0wVbCk zk1VZ9^YqJDPfR`}59<^cTw^$tvlpUOCoq_<<&4)nT$qhvXgSA|hjo+7wJ{#bIZe~K zfE%N0Iag{PF6+j5JiR?i9@cR#_QrT9=XFiz@^6f;<=7wz1{a0nJf56`Kq}-iag0tG zIJ0FGa?v=Q47fuFD=IG3i`R4)J(q^(K;OrntU5nEV9EY;jz09!!3dWHuD8 zKo2IT5G(bYOVWeMUm=;*l55n1$Aoa34FFGw#-pnE3W1*vdB0^Kv|Q%E03pnE3$ z+oZ2epnE3$yQFVSpnE3$8q&8W&^?p>2uNdjwueW1)H}*wJfVeJc>w;wnjD!J!v%W9 z#3Z2Dh#1QRJRKcS)G;Y1LnS(y{Xr|_`hAE&P7*npX-rQnF6b+=x5)A>QusHQ^Fs;c z7`BsHj@Ux3?T1KS%1fD&x#eQNBFkMiCvz7myvoIee?^g#Xky^J^`WQ8!@s#5pm_Yt zUwD@fK`!LpK#Zj8(@2oU@(?X|3<42Ic{nLN0L$Hj2&IY?9$w{6LWHuA6fU51S0O?< zofIA#D;|h?<)~w;1V-h`;nPLK%pX8v zt{f?CANDl_3UlR5=n|ofE7E5?mkz50u{c)_ZFUJ~nUQXRK&f2&QZ4Gct7I z6tx{0b27s~laz!FF?l6*7-F3a-^a=DByE~UUk^~9jkm|WfWTK~&7a#?ot>%IL=kcl@9nf^3s--^SixGeXW%PbvTMX?J2{UbQbQs;@P_msq$Hc^84OG zp7SQ|f%I}=BS>FTJiQg}SQUf^Fo4A0_W@Q)+Wh^IRxVRmM&$BTJ!lPd8w}0hZrS}8W=ol2w zY(q0Db2#|jQCAl_txc$J0cNQWC0+J&pAc{L7~ti_@f!MjyIVV3^fBmYwr&Q_y*?IS z)5!a91YqP+Md%GDMPTOOsto)$%novf&v>bV?dj?25e=r!L9553-k3Ex|5rAO^?7;s z{nHRq7|UyEeQR(3($?gxHUcZ_4JCOBQZZ3pWJ5lUbPk*<6R6SZobAhxVf@b8M zl>w04T?hfO>Zm+bceZtf>vYKxs@Vlp$>&W#y+4ASKmJozfp6^w__EkL^TJQ<^3K*4 z@9I!o2x_WUfN?G?03KELe(TBqmY|pK3G^vZ^wKyw+GX>S>8;&;ixcFO;&K+vh?kQn zue{oskbYT04h|7}^bi~I^jHo;jkuxt@%LbJSH7n^l;6ue|Y zeSc^9qR@2&zl`fgk%8Q(;sO7ursH;6qiy}sD_A(K$9^f0J0*Gzo9WorS^Ww06{Td3kPQiW& z$US}($v1mHBk%VXU{8#~%01{t-I`|hboF;9n!QEhakr5 zP${nbvH~eB`7EN8hau$mzMwttgRVanLFWyFpq8j0xv>*MsaV|Jfh#+>pAi(WY8VZr z*@g+qK8!ujFs9&9+<@IJ4LfDB9hDR6Vv>YPfptRM>ZnNRX?)>E-f=YIXGGOn

giZf-`dyT)2Z%=g;2H0 z-1`EY|H2cfLM?yg^hUm3+MnH`CE2EGsb|Y^&RlF_=Sy~*2cbBEsygS(&-Vy^Hq*HbK zIfU9GsO>;p5k-{++PsrEGP*N{I_UN3qBVpmkPiXwHxWpD?`&V7-4jJCIbuc^hTqF^ z7qAruuep_G!M`-^*W9|O*=jHKA;6C7Ei^5CK@Hzk)pXJ{Sts8k~(qcXv73DScnN2+lF`lSE z@wYaMp;Be}AHaU5p^d!PIEL67MHoNHE3(>Utvz0*>sxVIvuR;R>x`bRrGsoo-Hg%_ z>8e#im_-iGdb&DFCrGqP;8()g?VT+H19bxf9cmyYmF$9x@%?K&s**{$3}>gOs@4}a z^7%?MpQYh^`Wf^xTsdT(N+wC3SP|>Hy83ixn3Wm0eF{4`Fo1CYG8eYy9S!5NieX3Z zBDFGao!QqEhpK`8fdpUkseKL%{WGhZ=u? zKJ`-EddCy$ETp9>;Ey?q{xSwkheaN6q?e?x9F7$(2HfolkbJYp91#5p`c~qJ+GZ3r+wqlu-F2fP&ahd_?)!tmdv=UC;tCw@$D_0mLVP0+h*dE}air7U z+R;+p42#%%d{bZZ;=mw=zho%mf8Z|nvBkp4v5ma1><#R>QS8zZ$*nkr-zD^41Npfm z^pTu!*T>NLr8vQ!+tt$E2Dd0280;kf2VIFZUpz`Tq5L~E7{|vXObYV} z<3A2$oD`KIbFevGO<4Jnz6fJl8Aa(HNi6AKfcCzRC=>T$gF~jK(Lij9B8qQX!4lXW zA2t{uV{Yenc_LuSRq%g{N2x`ID9skg-tSAL^aGe&t=jeHw*Sy~(AlB|R}TaY)nE zkNG0T7_Bu}rHJHHGI`9^*!sZ}sue1Kf87U&%M%bKf2vNj(!sR<=E`!e0oXNBK$XS+ zv4=iA21q|Y3Q#875jd1o*k(v}-vhFFO(eTgTF;A4=dzWb857~_R2ocN0;WrCGy&Dq z1%D2(n-cIL6=ilRb+S5&FAFNwOS?P71!!xFzb_V(q&uuTfc~ol3944V&RV@DCV`^@ zQPO-U91Xpuf9b-Q>M>rG{O4S27)5wO#VPtxMKE;_pkES27tc@_<#SxvSJ&0094s|+ za9Gy?SiN1;2GmtUAbT4}4{)XC${2h}b+50IP-RhjP!9s|sVJzNMaX-Vo$I<7RB3gu zcvTf$48j_=4zJBemVTtUDXd>|q;*3KYf^Qus>7TMB?B%1*y1F>6F4NiB?jnMGi7>0 z*$WmYrHJkXyZsl2|dD9rX-vp}8*xKn&c8A=$kr2l=Y^cOKmcy()O zZENpT>Qs1o=~qNdCly}2x;h1YBak;o(X&{*H1htz3_lV>=LlAf0~^{`hF4;}k+JhL zq{O3MKUfaPJC9w@uVQF4jS8)*sdsTjS4#v@S+WH{TO37H&1ggc5I08=LvGQ%eUf>- zv2B17^g^M16rqbEehDFej0(D3>`e>p&F`avN@xwll*J5sV9D4AP0ZqdK_7b^*1z$D z>V=$*^!p;OL%N*C;kl?VS#TF&(_5Q6n&>n?-c~|lwTZh3(r!$Uc!a#v)i&h36qO@g zs>n&|SVAIH$$SLxVb>3SCC|#ycKj_S;E3v8!Ead6*|)eAp5#IeD1@)fQa!L2CEzQ2 z(!`$otr$M5r}}23Dwc51rN#t$Sa2tRpY*|Hj2bVB>8xNML?wtNP!i&05tXI;V=4Uo zZomatJgV?Tm@0+MY!x3zMabfo5)mqf2)fdL4-n6cqAJywa2jBl`%-b%)8MrzJ@3C<|>aLF^|^p=)_xG)xvbC zuCO3>41Dfg)>w0W?TZpquyE$Sm*7>(e~G4IGmCX#*v;HUpFSy z9Kf99LrIUX1`&sI?WZ(~S8_xJ=J$QA^-asYK95<#s2z2x$B*+y);9w6J|CHx%^;rZ@PHq`_&v4>U6$3pY$fMeX z91JU^KJ8Xa0`aH{q?CB$ZUCGU1DqTO#8&kXn3n?Yr!madVZf}5W1>>xIL3_rPTAh@ z>=d?>l6)$%j&1|$r#|x699p6&H0q6UWEj}N$aO;_&$x1#8!T$2+NDKu|&2R(9YWr^B` z5h5e>IWT4=m}ab$Lf!jzT>ZkMUdGvk23Pq9{BZdkpWiIyAiE_hnXB=gvdJeBdMm^D z0@?w<{*yyRD=Q`M zYXEtT4=Wb*(!Wwonc;w49)snqv91eqy1w?Nj*6!4riJYtm?25WskXPmks{zjfPdl( zxLjsTx3UOMi(;2dgg@JGYF5!9Fe~oF_mA)>T^yBRle%$tV16%(S&Bo09qpZ`_P1lw z6v^$7(ANO=<{0z}n*8raq18G>1aqj|{u6MY`H)HjKN|tabE1%?9MwfmidJ;@H?}Wr z?O`Q=-SQ6b_)((Y+70*;Iv%Bq*M?CSC-Q4F0!{v`BDZ$`QnAlLaoYIEiV+Wre- zK-^7Irpl={{H?s6YevL{>nP`hDY6-DF-n1EVizeT#|{In`3`_fLWi>8xlY5B6I_70A0 z>w3DleBZ^zNM&yKyc_3#@dQoV$h#;9IM+vU#+RUpGD&Q>ev1Ej%#(vLI zb@#=wU=SlY6D++1a0zg(k76mMEkJX!AB5I zTo!pWicwNFy}h@)3mBct+IzY>IXSFUCnXB+#Y_;7)CME(b_c0{6-`}w1kHPpQf5Q` zNlxzwz+zzZY8-FF{UjR6-^9W2K0|_er#62MpiMql;SbnDG*LHCMZu&MN7j9HCI2r{ zTjze*)uwD zGNANg2T3S5)ulM|>I1#|H)O=G6xH8<7!3cD)yW?m_)$8 z5q@`%&10-nI@{I!$zRgO&L17>r5A!-UlM7&XCsc}s!Jk`RrQtS)3XhY<&Blu@;TM> zD-AP=)L2Jpv)@Lhg z00}QqNnpp9S2tGI%rsW*fS9eWnO-@g8eo-kPB2F8i1YaB#;R;%_1wzZd5uP45@*Al z%E~%QoSKyT>Y8lrv{{uEjag<4^VuY(y7GFwA&SepXcJLv!@P#NO5_)GW0bz16XB?) zI_l@uQNe~$I0R1?CBPywjH!tn^C1MfEdhfuDk&o#Ln#>wcfc^73{#B*y=z71mzGK! zlCw&s8b zR?exMi%MeHUV+7!1U@^bwtPCOk*-BCo`&j~HMj(2q>~})>T4TOs=OmLy>@PSb&cU9 zGfLsiD6gnAh9xtw`BYbA)mvqfc`9maz*f_kt*fn_V+>DbYM577S+6v=TQUbGjM;eR8ct|vteorVKQEcbYlX(%$z)`-Vm6dp0V(;(EX;>u*e97mRd1spnOfUe zg>u^$){U!sgX@)jEsd0}f7g|i37`L6l*Sd^t;W$0`E{?ZzIrZf#{9}`;|X<@*=bO5 zWqFNpq9;5~KA{nlp=4S`Re8NpkxXl-s;zG{8j^{qBt~^IX-+Ln%dBMD3{>GpV@5J@ zdhI;gRJ4?Y*SBvQkH)7}v|)$?at4pNdFawSJX6+KK655)jW+gS(!3gvs4ab%SP5f_ zlCwi4r#7n8IYI2?&4)mptBnbVAdNpf9L-UEZEa&VRIej>5@MuEM{*@(U7Mq(f~et& z95oVJrmDkH3qhJ!eWMnE1XXi~h2CGE?lkO8?}gs|@u3fJ8v8uzt6(UL8N^48We}fi zCj)w-i44eb>ljdmHjDw!V4E1w63t;ij#)xald2X)&h8ra({H1$=*slW5Ql$_TLW!k zI8YB;43iEi7(~nq#xns4-9l}Br9Y4f2<6k*z&YlkRf-=nHtgpoLz2$UoAK2y!`bAQ zYNZ+t>8d=vx*BaWqkjBQau`+9OfQAe|D4^X$-)NTfEh9g$dNUW}!YNUt$W@|WQzNl+D;uk7rz5&299OBk`4U%Ig}?ffRbO17v$ovlrl6cAgoTH1}ej_qpHq2w>lP8%}9Cq2+cqZ`xx_V2-8X`H;0%?p7Xe$ zqgm{##I#|CHLarB&p|+#TV7FBT~k?C;cG3Rc`xGSB|c@f@j)Jl()l?~7n)4WWkT!e z1+x^)FluURFbj!9Ro9^LR!`R*ryjm4{wOg!v%Yp-oiQRYJ&L}zzPj-QBPT-kW=l2f z)cx7i?nx{Gd1Mlq2x_9cM}(}i=ozpvi9}V%df=_zO?9(`t*fuZG!TtKkGi8T@0%<= z>W-3i@%kg~C|R39J=|8*np(`L>npP}>dWU=HW<2%Dq?M2`Em0+nm_SXB*>?4oH02hB>v3##bVw>GSI5RHGJF8sj4IeES)-^J=CW2S?(yQuPR}G(u%6y&h0| zJf>>K_y}Fb7@QOv6JqhIswvISsIA9a7)M7~Dyr)%=FKUGMdLIy>n#;vTwoj%;hRxj zJ*R=LGOB0ry~r>n!Z5D}bFw-N3$T2FqE$-{9ABu?%$84|jsib+*U~gpR8`I`&!Us6 z;oy5}B$d_`i-sepN~1hNA2KIZ)fn^CS5%$g15ewvgx)Jm$5fl^4tmz3YDicd^g~x7 z#`Fko4XYfc&Y07xYE&5^hXEp*Q$;cty*KJ~eS@ECJqa2tKa$+b_2Bd~W8xJD$6elJ zxHiHdhG0I*Uq)sNBec2m8aPpJXsATxsVJ{2pH@AGHmNznRWonS9B@fBHCiI1@@WlN zyuk24)lMo;582e~>C&#mk_=`WD04#(;5>#ob1G+|>n*RJIZqZs^jJ=j)k=_83;j`@ zqA3NdwUKP77z{nCQ*0PdWNT*t0v6;1Ll4drt-PXwuRgsJL#6449;7MS@%5O`W~HO` zhiZxR> zfq8wX!&>ckSlnwixby3k2bL|ffs(V3WcXG{bU%MCiV5p_gJLm=XsilMk}4>Fy%fU` z-ztSkSb{Sq>bf8V&rDUL9ppwTP6$@wR7vB{^{Cii=usF zmdG+s4NHBKCQQ>$fX%}~Uq$Wo%IwTa^jNYY?i((}RNh#gojz|a7emqgHZ&T(VG_FT z@nkVsuNbKs8YZFH=_R8mkrP{4O!n5$XGh9WL&Ug%HYdVYU)fMQuO92Pl?$rMVePtoGP&R6IiTSdcY|_@)V57_5q*&u_HGtEbc`x$?!qChfxawG9ryNT zJ9tZ|$FN6Oa?OL%6fJEU$OifuBl1Qm z{p5;%#(2WTeT35f&&>}4u|fPOdvEK2KSKE>+#b!hc-Ys-EgOTtJ{IrQ>FHVnUr|Bb zZ%#%EuONf?LVI893PP>m{@;EU_tHc)eVFF$uar{MMz<%~h4QUq!*(rtHW}r`Hq*xk z4qOUrzV`}|MQF;G1KGGoU_KILVhE;`U1WX49L;0ZIY4lA%^Z|OE{R~5+01*!f4L!; zQubG^S>RH*2ksa*d`rf#A2$1U03YE^*#}u0d@190EJcbzHlVS|ZN9hz86nPM`w(mX zpYR^r_JV#6wd5*kZZ|jX50gNq$g9&|7wMx^Eje6jNxrHj-;i2TSk&9mg|aIazHvj9 z-K=LPZ@gtg>fWpF9sMu^5gGvhCt31Q&g>5G+1O z412a!{4&jmFyH`ltN1YqG0d?}2SbMa#ZsJsTh^MD_YHB(wO#|qs3LiD+D(sdSyM-U zYlyGLn*0}>Hh?kbjg=iR)>>DAu}~Fho%JsS#;GDbP6EZMNb4m~ri!#d0#p5(F&PI> zC92AgDk+9PFNv!Q;z|sAzQipE;!1JxR^m<$;>P2+sl+V~;!yiekhtz3ZX%p}N!)-} zVsd&ZbjQkm(%kO_lo^Y~E3-IDzI~Fl5OSAMv>}u7vdCu)-&bbmPVNg zQNW(H)}cQi<;nNDT6M3Xw1TsN63y$j+$}$S;EHyVjoe=4`LNpN#XYLej>)S0J=; zm(_PQAo!y>3v#`8590Ife(O4BNCtMx1Phgh2Ndk(7T4@EMGLVAobBVju{~gMQzfUU zv%jMw+qJ~7SIAgKR}}votv(m5WdF&0B9NWTQ)ZuL&HFQ|P8&{(<2JF?gwi*P+L4X# zNTxEm4`NVhe^&yda<66~eb1`~7>G43Me(n)wjfnuQ7ex?>6&$h(uj%#)0q}sXBK;f z=;ucEl~i`0Gy9PfPgMyFRwAMOc*k_4EmHD&7nLj6-`PH$^ zpQ|$O<;y>fY1l8Ash9lh1o4ITkE}Hy$VgM{q+y>Yof4x~WP6vicV}@4ba_(`lz6_B z6NjZ9h3=yiX^oJEdxd_1#r=&O)r(#zc%#J0uYHjO^q3E)A$!;Yc)MwC6UO&1nj4Ut zG_&NXF3vK_zSyGUMGnP#`m#+x!0ArhTeifC=_Tu>WH2fo{Udb}viUpKE6tQ$1e%f#Zzo_zUB0D~W%dyV76Av8t^-Y%5x_hkGWi21wep#OsZYy3)< zr4x*a5%6DPYLL&<9r>Zm%c!|dW6x)o8eqR;E)?v=8k=R2s1AV@s;BBJ!Fh4WsHM|VMfKQ#Azg}TVc@1dM@1_h+{!2{Nh%wvSL0>5Lq z(=E=OV#N{ClZ?-BVmLtfxA{FmI7=glXDFV+i03{8BZK#Z%Cg=3oq#=~!NkK<5}0IB zE*QwYPWdY&AhzEhWcO3^aF{kHGXcNqh4Du|PfWzK8%PM@`lc>ua9^0K1o3Pl^7trk zJV>M4*HgToNDQc9o7UZuVk3SF#V014C_k~oIWwH~|D3<<1M$%b03J5VUTY=Y2e{zx zxaHE^)S2yTT9oZtcnW-^!B$*uorW?`nPU}A`a@h)^9GblLrznaO-7O{yd-X7lBQ-J zG549T^qBY8%zar7mgLGKPPu#3{Q_#QzIL2#>O&(~*w2~t)gIrz0Uw7%Em?0>0zCyT z#Msw(Yy|;ZbAJyP70`Kku5)z~!@kzz-Y4LW!maZd@)bjO7wkW$@`n9WkFvL-^my0# z)fx;=O4vX181fW@3@-0bo05#wzgXvPW>=ReZrBNMlHoFikLY88cr zpgC{#ICqb6F7$mV`K-5jtT~FcS2-Uy?AyKg5h~s<$fiz=uhmHZ4v%FwEd`ayt5n{C zTyuASwoh(t-0ATS4|oUhZ18w8n#a?cr&~3)*ROb&$2@EZX56Rr-|=pb*NO3>r}h>H z7k70n@!9Y3*wZog=B}mPsD)@-s<64D=qI|@OO%Qw(hW!F`{y2?9phWJ)H6L<t$sj284c+`@JM)EXg9}1`;h^`+@Y6Z1j?NhR`>5${M0^x3>Dc zzwmg+ro?Ds;MWWyy~$>K#GR~RKj5*rie*u2Up8u$)S7}UCwUg?K`+VvL6X>V#6up( zeu|?Ppiw1sV@04HqvD4>#(fndGNrwg1ZLT&I(Gv(Dtj3$*;Y8_bI z)ZZ(uRMsSPDR1%;=I=s6)eeG=;g??8z4e)t@GUtw4Y6KEhnHrjr3NIGoDt~Z3w(W8 zPlAN+qvQAR5J%wk%&@mu?+eez_$}P?Ew7_hpYD(wTrwIEM`|GinfcQV6z?Ndp~Yav zU>$+fPUdL*7V_eKXqYVSb7ZYu?g7bPGQe2J!LMAFl&kvqzPVuB=nt{vjYJwHVeo5R zB^*Dal!u~HB)hWW5YH)YxO3gyu-}p7VY1hd=Sn+PGCs77xA`Uxeha^WAN3}|ut>(E zl7FGfL;_!0#4KY-3EEjS^B=}mo2)BBfp*SDV9-`a~s)X%NU zCGoXPe2Y#T7CLDs_hgpOW_O?@$?g z;kU3HKcQlc)(`Oqtv+}kuP#1b1)bs<_9%OyfG#HJc{>FSXH8})$_E~{CG1-SX9ICw z*&$9)1;x!?NX>$%Je260JO|j;Klsua{1#5d&(JR&#m&d!n32y3Q6$eC5W!iuVIOXP zQ-GTYylN<5xz`lR;UK5IGvN5B7kZp%vqJ2M6Z3)|)SR+7qpI(fY60me`=64l|1wvj z-%Wnquoy2jI#$Cjw+}}OjQ{alxL}CHa#d@PUc7ZYY;LG8HXu7(!K=1c3F6sAT$g}I z`w_{G+IEZLa23B+kV5+LBp#1tK&+|SZ;PA{C};Qg2EVr0Db89Fgb{)wPO`s_l$c!L zx3GRFka&rzYhOx@(`4PN+3pvd(};6z0*;s;PMqW$MByB%so4y4%vde79}<|y2=j~& z6MqTx5z=c_s!oe9(q;cgQhvsi`@SF1hS)l>6msn{q|gQ##x`ISYuL+db|oQVqg_$L3nG^9_*cC;m85x|+tGQ=N!Vu{Ex%hSv7cS4SZxYDc3HfjYGK@BVZZ*7w z;lA}?Af>o+4zdjULi;}g_Zi^|KZv})7&@s9(%j?PoIlsg>{`jvH}XyU8avT{gR%Ob zSc=kFT4yuc412HiGy8l*WQvsHJkaZH>T8r2DcZczE<;p)Q9?Jo-exCWs7R_myTx9G zsBtRF?+S0T*?ks6xF_chn{QoKNWR_WN#|Jwa7bxb*L}S!wEuWD8l0 z-F-Gq=Ypc}aATvr1$E@)qKFxPz-Aw?SVcxH@k2JvdUsL8UOi&}3BUt7Qq0gMn}%yu z(cqT#n9XLnx~L+dtAE^n2}-yyM$?`36ZS;B{@SACUUjq0E_hwhpl}PCR+0DshrhnF^(cBWqpMKv!TT}Kw z>>q!k_hsL=Wx**|+@t)LCQy=8C8E<5O=Uur5~|kbgTh@^jSCT=5#- znwo^bhFtOV-H|#OfsMK1oVz!5E&`i!#hv!b)ZGYd&K3XHXQW<2U`wuetzMl1IgsMzeTqJLiP@UQFkNwRIz~bp zp*n6`?UVi{I5(ND_^fo(D-qgky5ev0E9q+y+G4um6!OsY?-AN+y5hC5B>hi>UNv3u ztvD&23#W5$o9@(nU>=j6jL}wd0gSR-aqTx>Sn@4b9P@osLWPzqF7=wyTabL5<%+YrMd^PbRBXB8oo;FRt8f@s zX1Q}mB1@;Hryw-da>Ys6vh=qQsc5Q+>`PSTP#;T{P&0Sli=KHx$vk=sL&D8Ii+B#!gwRy7&@$Qu%w2}PnKc}pTk*{*z- z>izWpkh6T-m5)gMD}6x9Gzx83K2`R=bU8xfY*)UA_C@++goFL=tA3-Z{Eyua^M1LZ8$x2I9JlI3&%o;sDF6SbIw%D$C(`t7fLTIb)io>f;=PiU@wO#Q{)$2HL zc=5LFiW`(=qN#1RE3Q9Ia}ES;yX}gLjqf>?bd8a6#kI^2oKq0Wq+D?gbFOnPLZecy zICoj&tVbw6<%)ZjA3K{7DonZJROwRZZG^_9TycVQg=4`xRB_4`Pe#`Wtt{n=1ETAk zBG9I$T=5=slhCSCQs%Obe5<6bOS$3->rRKQWI@WWnI#i&MCNYM-^nRgTw2}dlml^b z$`xl+4@jsx<%&l}g5 zrj#qrinmF1-kfsfGbI0UP6TaB%1Gag(T;40aRj55B%Dq7E98jH$y^4SF!95pib)pO zLLO;c#(0*e0D{imADk4=Wi^6g0{vjE3+olF5}k_CP< zGQ=eLknc!389J$UGMrO6nPW9S2T37*ab)dex-^-?rVu&yJw+$8MlZ z%=3tKGCUCMWbW6j{5+syB|&{H5YtrIHhfJpaUd3A^7R?|;2%B&3?_MNj?_ZgBsU~Z z)MO6V6j?qc>tq@=MZWzehYMuFDYNe2dvH#MO8`!Wi)&7%Qzv5g6OzV6AYZ4+9QDP> zYQx)8?qiyfBf>;RFaPgqMvfK}8F?50qQ`(Pdf-Shk8nPyeFW+l22bCeRc)fKp+clXZUPY#wl)ru_vo~Tz1snn^vV6wb$sD06;+k4& zxQO*VRU_v--S1@TG$)73p&WRXaHS@55ELSdXE7&pxhC@i4k0pA=gUVOoD3V3li8>_ zF&`bo$vE&h_{YgmHBRO=&Cd@j#F6D=3wTT6=ZnG0;BV0dhu|T8uhmV{WRA%dS(cZ) z*KE>cI&Ke<#g98SNpKX>$*j^$9J_}^FvH?-EBFET4Vs%{`#85a@pdwQ(mWjT$9cT0 z{a5pF9uVj8>dC$!$;)$gpm?Mb`o*pMfx+-=Mot_;j9z{gYcgjNA+nd1b2OP=v14TA zDI47#NKS_5L!HcxnxAut5P#tO8hwQ3p-buzkJKP>Q|)A2kem#UZ917xG(Y=&#V<>w zPUa9qh!Qv-Q4}%gUR9m0$(*3X1$moc&6fXSiheky36W)^&&kZxWX^FyWRW00 z!RLLQOq=HBR7Y`3aeBS(C7R5MPl)W5lgh?cjfn`cEAhtE!C z4kDZk9r`($Qq3hknvh(oO6lNiGqVddFpC-azQSShXCe9)ilZ=TxTiLD2GOZM~3E8u>7icp5 zd8*Xn+0)6;dx?{|L(}O#R?+zvC_GT@WS-V^&P5g7Yg8X-3TL84SuR8c$&bBCsI z9;zsT<4h;BS(Eu09z~XtXApWhNJcVmX{JMbCeeYs1mnP2jDMUA?`on#;BQe1XRQh} zn9X>@pQDAJ3-mBBu$5_kWXSV(nVJ3GZl>G@r%x!{Va0v>d3|kV%702IuCtv7B$exw zAeyc;7jYMv*HVLM`B0^DJQzgsvzW@;U=XLiJE>gO1hKNwrrZezk?Q=hAr1tCSlQXa z@gwCkFo;(>SR{zAm4M(o{|q?9)k?rYPpjpfE#gH_+^hs7m8Pnxv!$ce5DzJFnxqnk zn*pV|b6MAtR&QI&*wa`2n)Ugf>TByNvYj}wpbCPaCOLzJYbhNaUQsX>Wq^xf*`+03 zIfUY{-Y#VjiYoC+AQV;V6+kFzyr=z8)C5oWp{R+T;u+PUa#8H*JQP*pX`4}PnoFrS z6jh?U*JMLcrG|K`k*F4(P(0Lxqe?uTGvUJa?tUD~P^xA`uZkG$YoVj1+1N82$}Ttd z3WrM(F~*N*mm@>sy+&kWpBhJq#958Xsf5KljmndR#Q~&*n>HJtEj9Lw#f&%h_hTd(els}tLOsR5X6N(vc6!|!9%pY*XosICQm=fj1 zCKOX@d^MJ8ym6o()8gTLEf!N^92AQwReo>;S*04UJm5%-=nMHd#80JSN{mBeF{Q>~ zv6%73*Zmmy-e*A_?niW}h;R52Z7QPJk7!X5C4NMciV!CklDUN{LOkwBM6-$zrxp^? zt0Kgig+#RX_I2UVo4Br!hz=DYE-NIWO+|>G3W;b@5#pgjBAQf$xTcT@1qv;RKZfF+(F!ciqgm0v_2SE+I%8s-|WTtP^bQXsIz??X7MM7ekf zN0l0LeRwb7c%#OTYWGS*9OFnjoW7Pa7GDq&)8@s9+Xsnh@nXcmgOcXOH2BE4Z6`S5 z%t3gXy_k7EPp=m<-;cpLbL04MsMJ{C2V3BO;e>D~J5ZuLysBLFcV`Dml{Y>eQK}sA z`9Y=-H+-R(Qsse9VtSY34p`Qg(T>Yq%Hy6;I~Z*8scj63+aQI;p!f%pV0&->Lgf=k zrDae&07aqVrXA%1*R+RoNR%FCik%V59H z+{WNCKiIjyg+{GK0#=MUv&TxA-eGXmNGf@k`{4hFyP2ix0m!}AA0u(ZQCD->!o&JKlIjC1@@ zM`^pUIuvR%&JBfHj34@;HgNtZ6zVX}3x!&Y^Zif@IM;+i9mWNrP@8d~A8IdMXj~Ku zH5)$;h2U+}4|Oyz?KUp)gKY?Q7(a=G7a5oO;TEA^76~sh*81W0w$@XP%R|A=R^y6L zu%pkoG8A0YYFrf#_8C`)f*6`!6AEI`xU?Ja*T&-@V_iHBf_@s0gS4Lwit973i^oCk z_2IZCCHIDS9OT~U$1UpW>oRWggQxWN80-BIE)WUL2IDCJ% z7k#TAjn;~9J9iql`7vm)5_7vBgUb~XbB7;;W-Bpw`Y}yj%mzQki@3{=z$J@beDS%x z*|^(}>+aWa_xN$(YZD(3_xe#_Q&B(nquOP%fX`s`^~3GMeX;o7?$%}uc#Qkw@hSrw zW6`)QrH*MCzlc#<)X{b00YAR8b-D3iIHX)uJmg0;fkVYT9K_L$MTffE{zwpun-yKl zjYs{6=EbeeOW4O5oBX(Tae2|)+SO+K(vS2m?ciPoCY6s3issqFU-_}i+c6=1+z-Ok z<3mh-CV%Y{+S_Cr^+Y(Lt5f2Bc2Q?P zU(^`!WdYvm2>-23bJ7UYyjk!zEA*`j_H_mOhQfPO;k~7VyiM3LcCEvolh1f+{PBpZ zgcu^_Ly-D0jLBILvVBG-=O`+7&r|#1;U?$ka&Q=XvYX90hJU9FOY!AQVKygc*||%y zsVodHS$S2EY#RSYGLJE*q7HniQK=5BQxvvz^~2g2M`p9_OS`k#?9zq2VwZ)>CnKk~ z9|@gIH-3-eKH6`Pj;F-%-;vqg6}V8;)6;>GyODF-{UE70Twv-ka&Bi~bAF$)p4w-PPOO(bR|QX3+J~<{cvYw2(U ztdVn-$!bn}kWU`@F{YsNKv5bwSDUPHG!vd|8N=q>WU`XeY~(X<@?%Va5?VX)by0Z@ z8WTw)c_9&#kmb$2M$TO(b4M$a&ngvVB9D=Cr$EpG#aWI$6(8?{W-l{on8YW6dfDKO zr{Wf1i;;7$U>w`4Lid?8UHL2>qa40|`ntgKn3MyJnaYH$NKX+e^!}#koi;9@dg>7t z4E1x~GJga_8oMjkC4%*ZLyp^cm>9oonW>Ci?_ zmkw=YrF3W`XG(`QvPwF%k+Y;j8#!A#w2^aI2PTf3%fg;GvPL?zk##Jyi6f6=`B?o} z-Q4>|WGh`<$Y80F%I7hSwZtGp)8V(pSWTB4D>B)~+LMoX*>EnavFNrAGY&|)AoKnN*I$`T+X5cu^a zBy431CG1;Up#4GHUt7vr!j`<>=Q;P@bMBoxBPac%zdv4oK9Y5w=X>_`p7WgViG>?) z|NSg-B3ecZxJEwJ16}|;^e!Tkbc`PhZ?)B}&A5oWnD3j(($-Ss^&dmPgR7<2JyaC< zXWZSe!4PfdrlDW?Vi@9H5^b}5Z+rm~YCfS$R-0qF2@wqqp-YMOhoOqxN#`n|OQ%{! zv{w^Fj|b7|eTMd#bNz>i z%YWuvUcD~rdCvGkZht;^FpnuWEwh$J>ycS|&qhOZazYnmLPZ-5KamCEVL`q+iCi$U zKt~P8QYWz%Mi$BHAap6yNwkHLMKYWUU21GAxVIZ4i*zm+y0o?_nFvLrq3 zvBkszKo@(VkYOBdarhZ*!k@?=QH6vqJ*WL3j4>lGq|}Bk^>?K*G9T!J{I6x&so$5- z;Z^9;L|2Cm!8I2N0SBUp{K*3dA$;kvKk6E`^^3N?{S8!GFPGJM3kh-lf(CcwoA~n+ z@CBxMA^zMD9riV&$l3f&2j$=8t3rIVPNw!xC{+A2?!Ng7r_|4SO8u;-)X&Se?Ig&`?Ui+8b#jUK5)2jJGBGVsXIdW3` zQCln`gH(axOAp+JyGy8z)3QD%T8MQbkGVrKQ$=o)@>^t`+$>$EB+C8={VVA-ZR|8eVsw>g6?Sf(mI(H|rS4LWHpwZ@% zg&Yx4-ZYLKUVy@GBOkGF;;1aouB090X*W&ihCnD0xG2nThN}_v0?mW`wn0hIPFg7D)&3;|U8~FSum++?e?o6`a+}m;7y-vggIzA= zk=hRk=3}yZWa>qho`XJ*Kp(S{e%OtUq!0L_>!UFjuSJuM0L4Z%o1YzXsR?lp>U2yF zJPDC~{$C04HH7ffCYhBsH*At_-r~(lAM?7_#Oz+w>mAT!In~DKke71gXcwfSE=Cqg z7+FR3^Y0L%8(|B(0IzmqCFx58WBmzRvQmyl3nNpYRspLb{s$utSI>X4B^{y_*$r>S zgXaii&MvP`H*}Kj+v?3zugyF7dP{bGtCtV%92!eG2*^0@w4AJYA(T-a_XZo6@dd?g zTL$$PmMn}$k?q9Dc>;-g%&r2}GD$k`Pwq6n6~mDz8A)|wc`F2JU+44-&aT)*=84D{v|R=pMNpxS0!(uv66Trii2kzxUZQw~EmE3OT7-y}Xlz*L)zN)eJQxaK+((lkoHD@)^pJ58ddhYp_#fkf&_5%PTkPOf z>m+H-c3<{6{TISc`t8^*gk@}Kj}POz+9CM5x2QNtI_M8?iUZ6#0gCJgqv-!Y_1oon zm0O-9eVxz0%-!m+Qyu*aGhiv5K^+;%FfD*@w>#Z2H<;c$D23(=!_x%0i3$e|C7+)m zr<{l^IO)q7lMQ6E<6JNGH|B}4g=)vB;h-@sK*ke#o!TtEPxHMC^j;UiNN8qH#kFUFM_~1@bj*pL?Y24Y@ z)VLEnSJz=L=jyA)%H2x~^Sc-3M|LwU)9z^u3Fi;)-w8i?{5KE&XWaSNd2rXBU3+%! z-90kDxO;qLgt(V>jfiLDSG;D8>vZB1#!oQYgh>@x=+K3W| zrb1~*5XMk7Iyp9m4V};_D%tRP3WA(xuxJvYP;_Ae-=U43U?QxFRB(_H86^E(0fKPU z8qTCgn58T9E@J|Lz&;AUqpogvsz7Sg@Y2X4ZXklqu_BC0IJOQEK4M%Cu!v2KU;qQ3 z4t++1K5n!|P*+kog-sKTZgV2^D2pu;PhdHN)mi8 zDg#EO_`O2bnXR)cY$bOmu0raiRELSs{l*gTF}LR5XWYou=mz_KS;wM6_C~Ox+I~YH zFb=`%N-Wm0t$B>IX6PZ~+Z5RO?C{L^5;uSk8Pwz;YNgVrO8hWOLL?b2^fTyT7U71G z3@7vvV=RwoJt7i#dk z25B)ZYNw${)YCJnMi3DF#9>!0Do9`43#%x1)C6r%)sNx6OSxBYgF_4?GcC%wX|MgF-cDH&sodl^J3Givgw@R>{3#jk{3jqRQAI(Xz)y{+ z&69WN2Zzsy@G%Nd7jXrG_?m*!Mj}Wk!oB3K zv%+mB@m`yVyqc1Uw+hJcW)V4Wg|pV)47Php#Z^B?LU4gVQ(^0gn0YIXkjlk7(oT|A zQGxHm21AXAT!H_9!a<1aYZd*ZuqE8tDsHqTbBj(#s2HGr0MOi`(-kUmG}=Klj)|4I z(aZG)QUdHl)EJu1Q+s+nnoC_?gZH}(2c^k?K1TMaSQ#{CZ3QzW&#FLJ><`a0@CnsV*PrU>sZL9Gpl282$O^xTM z@ERJuZRH8!mlA?E=W;_W{Dz-wma$(+1>SFwUih6eybZ?9EB0Sn$Q+_n=ke5at`Dz8 z(ZgD?Uuz&51M!rzh83|VHGOv*UMj)^Hh7Z@PmP~;QzK%(DT6|E-FkvP|NKgB8<5@E2jUR>oy@o&0-PW!OOT_+A zq~kn#BYdg|)ZE+Kce?sWQ9ZxzHUzbc^hRrxX8+1$|Mes#;x0G`T|FDmovZg_Y&i(Z!S z1Ksqxk&0Ng2FhjI+xxZrCW~}3C3t|%jv}QaVAkK(a#|Hbji%)H=kR1!UdG{OrdGpr zb+@z+;2|-skJSaLJDPKYI8~7CTEx;Cs1@&)YUAeMKyz;n66zlr4Q9V)-h8t8G+shO zqgt&gWusEMHAOnQ!9ZE%7Kx5jUxXMKY|Wo+K8}#r7U}HBRcl?RL2PBq(BL3im})rd zH4Imujj$K1u?9`gW$e>8YI=HSnBNKPXl`xy;WlVEyd~S3r5AXeNH%(vef{nB9AQuz9vo~R&}W8C0a|nqdM_G}oXI#~R2#dpEG~;D%d!O9To%@mZSKqwY)e^~9qV2Z z+gcVUV+CwmS(uC!u2}*|F{uv0Y_xGFHHLmxak# z0o$X&@NPZ5T1mrZ`yd{FM;)j(yf+Yt_bB@Y2Qkh&{kf?;4C|`yo}nHQ+qVo3Z{RU* ze;`iwayxP)RKyMh;%La@=Iy5MU?2{2euo!#s3Z=rUCM=lK3pFz4R32NhF@J8?uPD^ z=ryIWZqN?)NNKDaE)Cxzc5P{-8>&QJR~ktGJU`psdR)Y=FAc*>_xv0ztz<;(hUI{A zP(K<7<2g*$ehw>auKMQENQ_X;c)wP}T1sPNy}J#wwKP)CZd++sTYFC*&4X&DZ7&T* zpYx+T0@1DXOf{azK2GawRhcT1&gH$SnpNJqmiOky<}|bJ<^8x(Iev~U?}t9RD4Up+ zk6#8F-(WU6yFA*>gKX42%lmM1Abs>M@1wbcp6(nxo$u<-4dP8;JpXHVeazJmh*;mV z2t;c~{m;Pr$#(iy;0|)*^4|LJM0FmYX4&qW_!aNcSs3_l1g2#r_bh_ZvNZTCylb%! z1$uXS7k4!(kpX;vir9&=V46DQT2jPLmPO)|NPcYLdrnKssj{BB+MC-3`ugy>sk-dx zU>}qayXA@4O{FnetkUVTzYEJq5xY4Mh=Fr(pc~7}cG)Uui{UvM(q8Gd_TlrCzx(Cb z{#*^hA8XEMAeO^&Mg2StVSl#rnC=V{c}?Hk+SY1+2Fu5GMeG($jTLV0WH+8-mc?(s zgDzsj8pc`3+8_1wAnyR4kViMAMZ*~l*_rKY!Iljzuk&~>8qbfnqV7jD1U+U>FV~}N z_|umrjvyQ?XD9`vHfhX-&)x*J0XK98|vTG8?-c3xNGEUUGTX0;aD3X4W)i?sUA*Q^&}jgsek zhO&d*G(t7EwYTA%rMCOzcK~0uh9JRsS z^a51XWJKZVC9Qe9TGWc`CwT0N%txvo*YrJfh2_R>QPo-DdXmNAYVJ{*?ryp!gW#M( ztXgTh-eCB-H0>%Te2N@D<|eAlsPd4bhc9sQKRg93*)&wWP1oA89!vQcm>X%u!Ou)# zsztseU3Do|T8pwfQmNFOui_9M(I9^9K2des3Kas>IXulZe4!Ty=14c5<*It)N{_yO ze)hseCviXV>T-)qXB^duRmxj`&Te9ka&47T+WF;2SgPKtE2bt@iO_TDRiBD0 zPdTDQo>#i*gwi1seYVwbRjOLaJNeMfRlQ$R^Nt4L(=bq+XOLl<5&}i$W^b@ z5Gbt?7>Lf$5oT3VZjy7C&=fYgMb)c<)%-$?sQO{B7VVl|=fW{gmHpl3555PFr(FJBXLtrj=Lq%=O+#R3G^n!V0LmevOuGtG zbA%t$#f7N?1}wXG%GyO_U(q1+&IEV0IV!syX)PIe%5rcXFKWV8hO#-2hnlPI@&RCt zjVre3)-K`?8lr!4uFwLDH&Hc_Q2~=QOVlV;-|5eFv`K4J^%!(ui9XU8_9WWr9GRzJE;9QbE&Wq9-R8CwgZG3TWuK z#4&PlaJG4FZfa7RYh%GAs$%OX%vzfI^1VaZtcb6A9SLZ8L+5S-xh@W4XxagFoa5}h%*C?qon9`d8XVG-xwMy4E zHemCbgMy?kNZusk=^*(&5znxk&x-SEauD&=@8pu9Gvs{pI11jGH$;4mrh=Ti04x>U z%+#}9_AM@>wJL7AAl4}f%>?{D5w57l*L&q%(ttbO;1xSHF5-GGvD;UC6U$|(^yiQ~dq$35spY*t*D8lqm|BbYW}gO&0msu8 zkE(m7e+nZY*?ydZzpX(^emFzKw|R7J^TXq9^Wa&CZ}-UQ(U{i73nG4%M@$7= z`2`W*p{ejj1MUN3NE@ct6GePyk*;kLEqj*~qyAgl#uiS@P9ZoE->re$TCsv2p+4>O z=lC8??VTjzdo>lBjnw)kgm{w%!e~NSL$??4eVQDeVPFXvPrgX5)~iXl-rlfQ{tw`I#vZKkQYYIb$GSyvU|g@vFT`^3_HJFi8J3 zUKO%74O_dGrNu?8vf@XIv}a~pW>KTpdKH6sqLSs;dF8EigP9fAdllK?GX2Y4s`SvGCz3Zy~h>U?ypR)C#iQ zi|Ig(c>x_>Ki2?9$_0hO z-8nz$dY9@!U41flta%>8*pxI|j1TF`9ABoCzD{V0?os-LSiCqiGi`s8#ZT($8Kh@~ z9?!B@95m6M(g6LFBVb@Cy_prf7QuEGp9F~bb9jN`e!=>_ zUK3lrU$0W_ez_+2=zOK|FEc_|8Z<$(*M}tz&AMk)q?FgVX+LmQO(!{6ESjO&l3C0l?=h&oLE7B zAu-)x?Gr1>;p`EtA_q38yRmB_s>sp3S0osLKdR*)O(H4(*e_BHIV@_V;IOD=0fMcQ z68x2>zfSbQzAZz4(T*iH2E=M|^drG*=#N};M|<gg>?_GJHI=4}+wsubAP>T5aH-a07S9E1|JlZb+HFdZal?GT;(Kb!k?(Vy5prrko? zBa_i}uO**w$do)CC-(_Ng9;M~a>$YpjSM_J(B1)iX!@IWBL_~<#>(yF?9OJ}J5gy* zKdrfXu!{(U43+kTNC2nE@EWj(4J~tX7e(?BUVuxnvua6R)1X%Rv}SRZxXELUN`dc! z8Tw?jmsH7r@#(NgkSh6Mnf$X2%5Oj2g#qC~a&lvl&|dH*Kd!0V1l)Rs!sD!&j5S5_ z)Rjs|$)%o~8|)Ox4{M4XR$XLGojkQ!q3v|gQ>h}^ytPQ-dit5B%g$nE=bMSi4{lRl zC}!+~_Mle|wuj>H+OX9 z!pw;7aC6|AY)7+4si2J|saKRB^8eP#w1?y&)iJrpjQ#3AJ$@9s`t?CQq; zdiM-=Q0Pi=@@1Ny77ZvKnV27G3U@1vw%CwWk?cCGf~9>Bd>vrBi^s;FYpQ0vP`o%z zJ9ZOGi@YC_yyI%}$y?Cf_|*0El+=4wsL-_zgV9K&&S;y>j%4?4H6jGP8Jz+}mw3!uI={H211VCdljj#`s9PK*axXu>Sk>RSmEvNpL$x;(lmq`!h)kk zq|Wg!uxz4si$~WuhcRqk)bz;aiySsDfvbdvX}jY0>J?x6Gr7hs1$0|L?ayTcp$5>3 z6M@A71;@LNwMVq(=+!le+B4c2g;Hj*8OunNY9b*Q;wE)*1&DhO^$S zeYsZYlrVhA&57CrT4k%`ekVYR82hyid;)V4zp0hJEd=yBZ6BRu;~Ou$53(R?hqe9i zcI?j2%ToHTCYHI?lrPlwz;jD;bGW{!X&beTZi>&@=&oJzDeMm^QTv3Z7$}U)&X3AO zyj0uY<_NObE~#zQH=FIPffn!()V_cfxQWw)vsG{$jOC{nE=*75_u!vz2&wxwZb@aJ zZdUp`dVSvq01>g^P3;nK6@&;*)hw)ICt7$L2N7X;|FQ>a{Ks z@dwbnh|{(+IQS5CZzxi>%N&Dfy29^|wn9YReMNHGvEV#jY5Kj`6D8IJ-JsXw+f|sW z>+UH6w$j=aCsMqYt4l}y0XYRqO;6Olwn&em%C4jpmfvqX?*NFp+e&EE5o_I(MG&47 zxtWT(;g}ZmU>08}bT1i2BIRwg#nP0pK^N{Ez8l1y605Vu0Y1s&|ZW* zQ7Mcn)GZRlYdXZxwYWGpK*yuhLdNy5NjW&!?<&9K_1Ko{b7ua!ulxMzx>YMURZe_% zqrj%ylv71DE3~peZ?PM^s5=&{XcBb~dNpoK+qBXXlr4vc7kd?2yZw<@W7khLAMV&? zNfqHHYS${QlyfaGQCS=v8pt}|ed!m;-f16-Ku;x%#=AH>f^)U>ZGLr!uD#u_?VO#P zDA4Yt?fsAa017>)^e^`7X=$(2FY&8;&MM_g{YqL7pLIU9(|_Vu=Vr$iF_|r5d3=t^IG-KFcib@fJFrPtG&bcJkvs-)kn zE4>wXx32P3&s#j2fU3Di0#s4Dt>Uek#@?fFyF$PAL0}7!&^eLbpe?Z|B$fQzd>T5x zN&mnnq%)|c1@|B?y`(M5C^)aa{enopQ!^655^@4_44v&3M0!+Pwdor2^@OIQdQ-+2 z>1J&~=TS9@^e0N`_KEZnZOMmkgzlNbBGtORlazkctHvh;zCS5TD2JhLk=~;%4C&Ur z-GfB>&6;9peo~}&YRf_h)F(^&K5eBBP0P|G6J4c$7btfYXX&ll+R;uqFT&FA)D+yh z9Yc|HQnT!^y%0cpyBMsb&wFeNEQs`z#Q^>|?V6k+^-bEU)ec;#Q461vdOCup0_+0W zg-9RJR;@~UgC=#x9Few7t+~xRQt~5{f4{cG^=ql^Y}S^nj^1hJw3Q~(kCs7*w7#_U z`={_vYStHiJ@3V(*J#V&AOw2J$XT|eNk0+*&0$x9cEi#)Xf_&7IC5E$lZ@5rt~F{4 z!9n!TgJYe{h0+fOYURuz%d%J6amXpt3Ba)_atHkf*%H8>k{y(1z<)?b*n<&zI$`AD z4S0m+Mfzb0^Hi)G+xR?xJ*U5@8HqTNxggtAAU&yVNtXaoUEQ(1xO{wJwc`nc^a*V< z+n?yyYJ1jBRMe(@;fQoxZeH`*Q0ow^Eqn5?Xl~B-G`GTVy8R|>?GN>mjWc%L(~H{9 zwG*nRNIzX3K)K6qD$bo22IuU#a(mle6zS`RyEm&9n`c4sxVHJ-iq8+6gwseVTg-(m zDo*+~ah4E2*5vIoV6VZrDRu5RcHdU^s+SKo=Q_FvdgS2=9rNI%E4^=^W=+{ySmdEZ(%+=tsi{crOj85cXr;|ZkzTc3g-r7y*#J1Zm6?xd8*i=>OCbA9 zAQRE%LgxelcX4pu)G0Fel~T6zDMO}>_sw{d1?vXvl8DvP6o^ZM%-VZ#eUdI{lCk)4 zv4*#hq|K8@+X~zM9+e4;*6=hCpocj>+k+zr9`yqt zwpDX~-@u?)!vlK&2o^6Az}pr9034Um=_`!lb9wrseW006+1Bt_pUmUt*Z}QVI^+Yw zs{hNGE0me!0>rZ%tI%ISsZrf^TJ51hZw>(U06-Rbv6$Rw#G+=!6Y}a@E)7} zc0K6MVZI}b-lO%By{iF*MgNSu?}6urye%e&Xw2tFXKjv{JZgYKxW3 zi!<^}xzy0|P!HfvGp_$9)Q?N0W}HcZT&4t-8mpG4QZwFVfUFAz{yh9HO{Hdh%=i_^ zhOM)pQZpVgb^+|AQZqho>_fZoQ>ht`vRJ25GafU#fOM$Tj87QTaC)iKjL#Y`gixbW zGd{ht`v(lwfGrnZJ9w7x#sTqIE zNJXV)eA##tpo&V(c*3|B0!5`}e8spA0!5`}e3b=$DmCM4##ez0pi(p5ZL9?O5}wh< z@5`oAGwwGEz`Imx#`~BqT*MsyDC7OIj*F?(j1L%F;8mkiGafQNM}a9SHRD4DH93t+ z&G;}&bSgFDVHUYmYQ{&57b2Kdjm9U94alrRrDlAJor+4$__VPFdP_FI&&Z0^sML(V zk=2Pp`2-SST6mWizp0%TQK?Zojh~{T#ZTh%fS2G?i&GY<9onGyH{pJ@a=UzLBr`3_ zzG;Ct6TcsUq?k|ben^Y?)IJHR%cmA<`DYI7Kk&PnNY#?u*HT_SwNTqp%zZTupIWG$ zvLb41KDAH>`H8Ta4(0H@6YBgn5SEBjkW8H>>U2J}&@l>77fC*~&~XY%mouMQC@aN2 zKDAJf6!+SEYN1|or>!v4sfAxfC1i7}gld8hFql+;SO@&Mt`z-iF2jfP%~^+~K_ijIiQ0=sZo zUpmLwX`woL0jl67i}YxYhe(u?ckB|;)IY*iLmx1EMYKk?Oma1eXf3sX2kU8i%i?(c_6%9zg0dLLD(Lx4uiuOq@*Er%Ybx|j~uT4#I!UQO%6 z{F`ENeMveuYlHC>)_seA)9B_P96C2^3kTweT{<^w2YYqoHl3T*WKd*|)S+{;4jB}K zBi88LtZR*LqY)?#(Yaa89^rZUDvZ_Pmr6P}>v)lz>D;V-me(mdx7Y#d;HBu?%%7*8 zLVcE^b2ERTse|d<%wI}K5uKa)E2#iYg}lA&p>s3;OADFFfCA{;%wKCDqJHtwxtULD zdb;3BHiAWTZsu>wpl}yXnj?F40kp%D()K^#Ix9bbqP8*GvNn% zbI4cd&1wzgqjNKpMLL-hmleWH=?EX4n^~hNOVGKQwHl_F&dsa~RD0>%%(Mn7P3LB2 zG?<^x&0MW1WutQG+{`saIzE8%tlR5ChzWUp)Z^b8qQDWW^VK<{d8{T6`I~*!BA~~Q-BuT1N(CxIydvmvN%aL zwnvzo%fckt7+_nvM@VV5CC6Q7AIo`Y)4s`j1{n* zWnp%#AR69P7AIo`YrB^{y?1U z<#y!6%wir0#Ly5aH#7xUWENHKGJD2yS zYF2scTHc!*o72p?m-pjF<@hIqU zIyZAP07I*E#R_K@Gzd>&KE^g-j%f&=(o5%Nj%&ywIyZAd)0U-kGbe+QI-Q$&tA;60 z=VqRjP%l}V&cS9**73K$7ZE_`X5OlRY60g7>a0SzOE;aZ&74vIHwX`4+6yS6b2Dd3 z0~|Uxb5>zW(7Bm&3PLFjpmQ^yuOMaU+{}4~t;`P$X7lcsat_ylnPL#k-koBPxuW3& z4%TCAVsEZ&co>_fBF5K5V9p4$Gol-UDbHx(f-qOHIs`SYw2gqG%eD(Qs~UcZK&%*S z8=Nb03w)Eoj5p9DC5af!@#inf;}6#p$5N3)~v?G?oO}YXf$e1-O+J$p~pnQw1=4MW8jHzMRM#11(7!v-K5v58K_UeO@~MXdjc`$`(3#DPr=Y-SOm|Pa`GenEdKo9)tiUzg62Fg7+YZ zd#h*Fb_t;yVlLO*Ny<|lS+U4_%C6!O&Mcd^c$oaErVXWWt~14FG@)Yhix0^n<4|-a zzxeC@3U$pS{#8w9M*za6onbv%X7Yhpz#d|E}0|Z(&2bWEH z7rzuMtwq@#sZ?stS8)iBXb`^^v{<*TP$59=XYz}`aivF(@y%uOi~q!{)0q6?CsrwM zekQ;8+A5{A^UF+r@we&mO&bD8|&uhbA4*%CO<P9Y^04Bf08cl`ygu4K2Xxz-y zvtITsV)9F@RdL$|u}(?Imf2zQORV?GZBCCwgIDa-xJWcA1&o^A6m0N_9VWlTMkSU^ zeu*o561#mRHnCimiq7PhxKhizhsiIo*{4xVeu*s}m6ypcu{B63IRFydJUW-jFR|St zXJd0P`6aIMh^b&5CcnfEO+~k)G$y~q&LSOAO(k|oG1fd9lV4)D1}xd$1ASt@CPn3Ynfww5G_5v=sA(W^P($cUeu+bx zLTBEoY{(>Ny8FXdzD00Ce5Km;u^1tt~)Cxzr>Lutz_~`T^XU!vWM zDPriIA!Rq(rzy(h{-Q;%!|=W*BjVzFEEJ7FOl_PJPpMg zT2B$On8`2E>jk-$=nbmRi*hQ|3+nfRf|&dgH|iMlQzry_JR8u})IA)%>_0hOUBu*< z7}V81CcngxuGE?P=4(Tp&~W8u}Eky_);I&RBi%p zy+Yv~Cco6FE0vIvOUJi#2QT$uP2t?yOP$)R&~`fLGNVW}Z!J=|o_?n3Xb(^_`K3O% zO?jc16_a1;vF%tT8RQ9MQSaX6D*V2n z-L>1*>P&vAU;5-;ezMG7<;%~Oj_%dWb&(d+Sb!HJ%R-h1kvu* zY|=J`A!a7Onm2icUM9bqN3}g;c=0p&)tu9Ijg_9ek(-;f+P<*D$W?F6lYvU7AbzIp z87r^MMNo4|+Y_eJW+uOycWB$e8k1kmZvy40^6lDguVUsCHDC3~Z6?2(o3$Nag}0gf zYM$1#Gz~dSel_QK7g#n?yTzkxNG8A99@%`6!}3gibw879+)_aIoTl#QvVl+oP^^1= zs!?}DYmQzW7@^K+XB0|FGc zcR;IblFHx0&^0-sg=Gh1oS#>ADv^rP}^BM^8+Cb&dLFv&Q6C_X1Yn-q-R> ze(8VXmQ)7nwx#sHGgN2tOaGp>0Lw7>rG?=~Fq2<;OOf2+5ObOQ(tjw45$Ul|P`G^l zon8tT>2xN)^aDkDY+h?je(6ZWAAn*+OTVE=>F}$i;}w2?%;cB8uSiZi7C43%=_^gY z7ki?_T3u)IOW#uj^f39Q(@}pwPJvR>6Y19$>0Ktj^a{)G7p4QuPIFrcjXGjYKUoCP znEcYiF)e7tIBmSOTs-y%`Grt>lRrN{NKeN2Ao zFL^y`Y<=mk`~2y;RVz4EPJDKw(3t$vH7m5T&`9&r$AT5$ym`>8aa-D^m7bt%IXt}B ztI*o*kGvYm-nx3DuF~u2O}Ya6q~MWMX?(M;^j6^Ay2?{MZ}DgXs^%UEP(|q+8)e?A zY3w};XA30LuYC~MLL_ufWHx9^EDA{_|2Ch7&Tle5@Cm(4eIm1@Ey^f3uO4hunRjYN zB0686$c$>MHeEx$p3rnuZ;Ht;)2uD%JgO#<`9vw*K9M=1E%|KzIjVJgCn@u&SM6u= z%k0q>hB}j9=FOUdnEWz3wPm4)$uD!Cw$j&_{4&1_lsk*F%vNpfXs4VPpqY1S3U1vF zlV2vOS$5c72q3*(3|6{KewinW0g9?mWNy+{t#;r_javAW)O(oxG6%F(E438n_siU% zNu4oAWNa&YZu5?m{K(|ruPt%?T53C+wI!>gcbYjf`DGq0gAf^gY3uh-;h)s3FZ_CD z^2@Bzmcc;?^b(uNFY`zM)M4_=+@RTLIN^Ah{4!l@)E0t+aGCrv4+d&ACcjLtwBwLd zrW1glqAv3wTLP3}^2x;|BjZm8Z5Z_(qgtnROPxNcGJ!>bbASS;|Ty9?T+0b%KewjsW=h_L?GlzbslV7G;Q+k>FGVjz>G+a3LCN7g-X4Q5TGR=oNli%u(Xd7>? zQZf0hj%ahCbAsS7`K`XMlu|PJt#0FeGu~vux&gZ+V4b7lmsU+4u0FawF6wy;DL^Zk z{OWne2v92~zk1$=2!Jq?Up?<31!%oYe)T-V1i)-2zk0cM#8v9agqO*$o@a!BU~DG8 zdY%RX^oq$(UbhZ_=uCd~Jg^6V945bd-nIw;lwk6!=dnH&z~r~~FaI9IZZ#T{-`cm4 zLA$6K(U|m$5CO^N_X7aPeJfsFO`K_1Dz^}JA z`WD1`*%0z0`2MFC4H`1U1GDaE!c(XjcK$QnE87_4E-C*ZPb=I~(f z$b@LvO3ql#6b`+J`DYB4`=VhR1+z8IGLHvn8 zcd*D1hwX5iM8i%>#ML5BnjQF)xoiv(o}8T|zM+O)ukHmaQad#CQwuZsD4FEFh;4bBYGv7-f`)+iHputHbG`18g3=38#gLf zJWCuo4LNYiMI&^c-*86;{C;cldF0kTKp16->!uaA0f;LAA!0~0QXmbl`Wg~mMPVQ= z(DdOo+57@g^)1cO|6s;$__HelwNxph;m=2)G_6Ve-k?Gloth$g#XMeASpbz*!=+Xv zRjJR7j7;H@hpT=qsW;w=FdA3H!fiIC;l@{zU}Y?P)DdhY!Kzp|@k+_rxUqu-Rk3i! z7Koo*MZMx1E76Gl$H)%H7xD}8t&?X=cX*3U5BY7h5&HKfWCYYzBhQrn@I3hd`(fxz zEkY_mcgU*c=?+8hGHya3rgaN`m!>-mea!eZ(H%Y?*GWQ;7<(uOv8fUC|Ixx6y&>e>UmXV6?F!W{PF920^hoL8ow?Lri z4ntot-VTAHI}Cl51%A52(ASJF0~bJd7<#u+1wJ&;+u-+Q(;bHHH^zZ?=?+8hGg`SC z9lFEN`(+&$(;bFBU~Gd|jqWh?knsfyOwk>NK4egn)94OEA7+V8cNlt@MK0Z8=p)8$ z2xe7d=#$13$gD$m82S`D72RRz)5bRFE!hA+BP&*;I}H7etWFfl*N_O)GLaV3qIOzD zcQ}NA=qLU?AWJYER#EP#3EH5lZ^M0ua=T22Br`3_xoKU+zyBJNVy44)Lt4yq_$Xnm z$mr}6-V0RZf1yNVYIbJ4(UvD1Cbj7^dE6)ix9tTHUZA#JMTNEjYXwdw+Pa6WEqs49 zR8q!lZQ=J(fmA!eFL9l6cc7H%>qGDqsLwS^BE6oVty*xJI^8a1FUG%Xr;l%6=-!p*F5 zgqU_&+ToW<&bILJA~|!mh5K2aP@HX%0~D7_OR_5DJwYK;3T~GTl+q=wfS0=GIiQ!&J zVNTw=#OllZPUS{$4{Kuk{^fUB9?#5XELFs-s zyK%Ra?x0>+v~&C(lS*Pwtmi`O!n`ow%g+6=Tw%Nw*}31WgZ3~v+u(d3JFg*UJDl%l z=e6YQfb#?Fyq=t$a6Z7!qvXuN`9XHJ#M+Jf@7aBA7;lba2yooN7yj|$01>UlpS-i0Sq$c|HF<8v4Igd{+b=P#|B2>_}}b! zMQq><93NxHYhnWnbHaRt9d|(k$H&=mFEo?Fe3TvULI7|)#*PPK1BZqA3I6+|v4N|F z`APo!vDm;~fi?39TtS|lA1I9Dbt8-#=0BP@uqIq7HIAW-`A_We-bf{1Byq+6 zFN@z5smu;9EVkg?(2N`>52py~+0Y&#ZjRr*!@P3#&he zFT^Rc&a3rbX)$M`iQGT1QCb2p#rV ztCOTvG@;#&Kk7teNupf#SgW5D@JAA6kF{>JC5k=P8lZIsK#D!q%F${PqVZz(SZh!Y zOn&xQYsi+{A3FF#;jc661T9@D?eYr=axZ(Vb&}RSvALZY8v7B>xphRF(tWcCo!#ttd?|BPQDqzdMwm6Crm$oDGC z{H+mMg+VGidmh6eF0}v7;E~mO2aTY=H{OFJMF{tlvE74vTE~fy#I4O|nJSIA+dA9v z7Q6WyV+7vTeHX#3UlOJfqS)5oxHLQ}qYH;VLW5+5*Pj^)QEW9fm2G9}F}P|am2G8> zoXI4WZDlRBzXD}%ijce^-?O*raI;7x z%v&p}s$_8p^K8ZEC~Yx$Z-1(SQfi4ti8ZGyeh9CL4TMkZ!Y?~?DY(HA#6=a&3Vn_{ zk4fWHPY)h^2YYEVo?PG8gjSL;|IGYg9C6vb{3KqX6y~4vkSk*Hpi0VK!?I9paClq_ zF7d1r!L|Pdx@0?wA?vj)s)+F+b>AFsSeUP4kESgg8(YA8s^;r?5XTfrZ*S%b^lBcS zUpDV#>`FIGjC^lkQB{nJz0daj7wkL1GUfR$M%K8VF;c#fMRm?3^(OY0k<_n{PF# z0uoo;Yb4AsnNKFLGtgBSrsrSHzh!4aY|IwMhes|7^UGR{m<*mUxrXnh1fXocBApMA z6UFjX>3ocw$mrLk^9gbyMPHZBACME%!Z)Pzr)%KE1o%zq#FPLx=D=@BcY@uRpS~^K zjqJu8^&RQn!)}_VzAFVsr2vWho)q*;0h0H3QgDkDAc21`1#?n>B>saG+%5%35q*U}WbbhC~(l&B+d#$=M>A5I4k(&kvJ=SF^RKZ$K^qcwmONk z9~4O9Tm&jd;_L_eNSyuZAi~{HjY0*HI4kYtk~m+Ek75#Mj@?*HO(V%OSIQv2`P2%hWdUNQII4e*wiL+lPQ=;e_Q(96{Ja_V#|CzERVcCvjHs1dup; zlmR5pO7C#rskXmKOM;_C9|$0EE)GTEG!o}>FiA0trP!9si4`lftz~fjSAxVjD0&JO9B!@n9?iAqH4@RQ zFC%n^{q~yDST|?~d!#hh$6|YJX`~w}O$Nfet~8RrC0e`MTaOEnIF~E|KZ)})K!?OR z2*z`mtbL8dxg-)Jk3-^I5+mD(+b~-L^Wo0o4rg^+X;=`6bII5PNt}bwmqFsZtT$D& zY8B8Gn33SvoMzU&ydO6z$Ir3l{dh>6m(2`@2z+|rGe&^Kd0Dit`S&dE!_9&02EEJs zxEvDaWfNKyh&F8WKZ7)AjK?=F@9mk8I4_%pl7VSi$vulSX;~V47T&ekhXTEqBykSP zu>LODrijE@L3k?h@iY^OvqJckMI_D& z8ARf&w9An=2O@nW&I+?Ei8DjJ6wMyy<;l7LL@ua`_-6%If>=49%f)dhkHS;(mXhn6GlCq zV{NgFhWf2Ayc%1~FW^*fcwQJA=(vmpi}Oo(XWiIHIYJ@_g>l7C@#nTqysGUODcD=N z#+9@a91A!8i8L)FjD33VAU4y!III!vC!{^0^urF6trCo_uf={ZOcYPZaJJ|33-;|9 zn8MAToh%4r2OS>b>1W%lu^2)|vvX4gzBg;^l<0eH^i_G7P0r2EFXqP=#)c=SmOuq< zOdMS+qk9q=rGLiVf4Uu(t$ZP*)sA+8_RH&H$iI`2Ti*;&=u$rf%)i;+DvYTY0cGU2 zO-_#!VX`dz_k{=QU)767_2bZ%ld-dx@zc0FW6 z<^frc#3KY_4|IeJoo`g3!L>DX?gIYX6FN7C{|=M)U)$ba1n&nN?_yVEoh-dqLOdwN zss_cLN?ZMUsCQ*-$6MieA!Bbet6%ww+i(9Pv1gsFdk=J?Y67{Y0=7?N>ZwNdYR!R8 zqun;q-K#a|I?58f_3{}f&b}eWzGKMumh!^m9_g{fdA-c)tmSK0808`k%A- zU7T8g#qTq=_C0Dhmxt^s|0A4xJ{xP_C5%1twe!&NZy_xAwe!%KjW}^HVgAdi%QF8R zMe^xn3WzI*K|B^^I|9usLVe{WT$gF1mOHPmZ??DJG*#JLdP@yNh=D#G$pisUHf6mk6 z)H;gHf6o9&KXK|zrObaRchm%JP}Ps%Cc7!y?VA6R%(N&|rgfNqe-@Hr^WTRdEjIss z98%YsG~Dtt4(!+Xod}W5D|fS`*P1lkb_}YNV@(=vr>uySZA}{PAU_dS+t#Gv&VK{~ zwl@^y5PoVzt!_;kK1KoRB56$;K2AaDa<(Q7XQkL@O&aczV#k^^+)M5{OWI6{NQROb z#;#sgL|#HF+fXg?YErnbo`+u%{K&7ESP9D3T zu0~23o4d!}M`i6i=Pe&6kFDmxLl>SCv315YyqeYm|E5@6fHZfHZ7}|vb$9Y_8jKu- zW9}Z?!htwq*W5j}gS|R(+uS|YWKd*|)G>FD9Wp2eN35B<$F4R0fVxr|GHH)BdxW;3 zd#uARm4@!I<3(~dbdUA3yjB^yS013ASL$){=+9ICirOmmIC=CJnmX97CHhMVDY9#c z{z@vaUmsxC68$eNWIh!Quxp9_S_1{xwM3uP^t`hYWY-e?O&JtE%gL@K`dbZy?XP9* zTB5(x;Fn?768*h~_t~{X|4^hWwk(J~RRk)wYl%Kx3@T~Y5*0P7=4Fy}yOyX?qz)SCG1+F2|v)AL$+&)R%;-iT}w1sq?0LePqd;b9pSTUiPmV!5_T=oS`AZd*AlG@ zRD11OqG=6O+O8#<(O`bNmgs6tDI1k**AiV*q{C*L{y2HGz6jykwM5qz>Fmf=Yh9;7 zO4zkT*J~JVGhVxuXoIE?c$_@isOihtwL~{)IKN#>bfZ`4w`+-Bq3NCD0M+(41!&Pd z{B|wTE6d^>yO!wYvM|T4CAy_7%(nH|E23M=;vBn{=(e&j87o5DUKZxswM4Hfi*xK+ zqC3jM9J`k2&ayDqt|hvwEY7iOiS8~7bL?88do-A`FUhqJ4w5x*UNwNdfk2!UdhA-F zP32*Z`9O5vGC13=CAvQlCwsXaIoY*D4+P@eGY!XHC3-LrM@J6QzQI0*j~*(C3$km8 z9xe@6=i_SVy}C5qJ%D#oa!qNh8?=KxQX1=q%V#3dYfB^DP$lxZ(ntc>h91%DOT#>N zEzuj61F~I9^k^WA=P+6Oj$KQ%xik_Z6x+2#TS{YOy}J#wwKP)CZd++skzGr)y)?Mk zt|i(Lhz_q$VT0>ybm`A(ns&|K8j3I+#otIeD@8AXy3C4M62TdXW(5Kfkbay-djmil%gyQ z{5JyAvXXli!Dv|;d=}od*oOkWJEkh!)u==Uy4!Hy^h8-OO&#{*H?(NkqT z1=zJjPY3(Z?OLKYmBx7NTB0`x0x@vJoM>(P0haEM!qj#da;xGa53`t|dC6AxhY_L`MTKUb~iPL4)uV<}+Op(J>9- zQ+n-MqT?E}$gU+ip=rz7wL~X_k-A+=^i~a1-mWEjRzgeLwL~ZDcpJrw2(W93-l~9V z0jJxwM9(UOyL8jdR-#i1;0ECVOnU*k*$Q236VaK{0LQK+I;$`x>{_C83PLFjuxp7v zUqQ;)wM6F`R?*+xL)KY?Sr~I*Aw+FOME|P(Ivi3)*5a3Gwc>Z;6n<5o#D-<{cd&uV zf8kP~^4o@688j!I#$E2M(RbIc!QGeh~rbw;VO)ds%74 zTyNd{^m+7tmM4_F6|cq8`{)ZI`aag-neWLL6#B+)D$LJ<8gWWQ-(OFO#XIK?qdPbX zCP(1m1FYC2DuOc*eW0H58>AJ{PjTKNhmpa{ecqef>17-75E=(sCpu2RNFd5vk}sAGb|$qz<+xFc&bk@hMaFwM<#8L zn>3OmUGI_d!;X9!%x>rTJZNfhVHAwvc@UtCz%+!9HDck7Q};_cjQz_8#QXctrvA{`pEcU&T&p zx}gI-8#onNO2x)G8CLIO2y5fqf-w3*h*w-e z@yyw=FSxN&IydctY7wd5bT$6?CjHTdKMuoS=gL0(apiOHYcu)3*Y>~J_AeaYZvvKm ze~tbi-@nEmTm1N~Z-HhHY<#x94S!7F4;0zA^dj5#A(SWm7^}tCk?x523SChCALGIU z0SEXDFBG1!ZOqqT(DN*8VS;U4Ld9k-{zHGbnNVwKW?^!CrZCzFo0{TNdVAzDmi)-wDum>a$&!V!!%I@iUGJFi{hEV@N0>y)P zHR>X`aYR^E+(Ihm7AL@8IqI;;fCuqK2*k8rN_Fk(z$8P*^9$0}^cDj=h-7&wKF5(38A4G?N*hAu z5OPUFC{mU*gd(MG2sHppiC{x0LV66LP66sMgnAwX9z&>62t0;RBnU8sdJV+EhEPqY z3|QXa_cJks`cvR_Ln!KkBBmKaaUBO5LiNC_*AVI_6qv^likh6)5Q-b2*AR+Cx*^ot z5eyqbb)pVCxm2sAx3lA(D1+ zBFFI1Qhs!Dd~$I?gb!0;_a{BFt4VfaaxOozke{0`j1)!-Kwd-A0Z35_`7_AQ+%T4O z;Ugr@C1DBmXE-t|^+?PYU8vb_mtX8*Pa)MKcFzzye5_qM11wvLFgDMKcFw zuKlKH=8!E{CTDDlW}cuqkkVel6wN$I11JIfrfB9DY4o{FQ?%$_9&@BAnq?UC$hqWA zvl@(>kp#ys&AO9yEAv@w#pQ7)Yv8m_JJh(y)4Nn0%Sez=m-q%Bq>+bOx4M68y_Xx8l$u{!QQ>;mUon!KUCQkVHS{^X(2 zF=>ls#vzK3JPZnT5j#bHM!rmLeo{fiZehvyNy5+8ir6?yeg;WNGq^YnKRfW9#j#Np z==N`w_pgOY%Gmy`@_kgnj>VX?f2&;0bA~QFCo0z&{|jDC>yP<2#o_{_{afV*<1MUv zJO8FR$U!*vZq$+|JFr3aZ`N3 zyx;!KifZs+`!~zdAo3X73COi5vSJ#hjQyKcso~soaf8Sg+rL>WG;|sJH*2Mais({v4<;QSmqa#$Zf3xC#bqV`7E8z!vbIA5@R<#E5*}qxIBArZ$d-83ibcE0T z&8pFqCG6jop9w8L$1D)u8DE?BA?LO<%_T&Dx;h{Pu6wMz7Lu|7KmG z>78Rk)%G_9Xwg0V_HWjeWpR%Eo3*(t%&~v7wv>h0HetAxu(d4Cv469+m4!L>Z`Ss* zFgsSYE&ar>9c9exV_HWkCvM@VV+_KnJ7U$T%S-Z=^9Q!wGj|MAe|7PtC1j44k zWB+C~m4`WIM%KP%aJK!MwLcIid$}Ds*}qu_0&z6tdF?fX2;(_S*1lu^W;K^aVuWJ*H>;&I#%up(wU$Qe*=;KgE3$vH+Dn6r z?cc19K=g9-c-%1RY2GB-rT0+G_&sI{kTy%evU2gN7=tw$1elz+P_)Z<7#dfAIsXmS$)qU5N+7#e+J%_v6yw^^4>1n{>>WrZv>`gCHE|X(Xur7 zEWB&64+VM;wturulm*k&VcWl1C(9y(?cc0ZWjzJhzgee)edzXY)=i}`9{V@z=0G3@ zPQU$|^&AZuZ2x9GSAzuFzgf@I5CQgYR$kK=+rL@2XzCL7Z`QDeaTcx_mB zw12ZkG(-veH)}KiduJw|}$FN~qVmO*dMzChK?`#fu2Af3t2?K(&DL1a(#++@+gt-eyfHfE$DdFzp2t z*}qvcr2&rpn>DL2CG6jC?f7L{H{y3{ z48LlA3S+FA+p&Sle-W?$U>1f<;7W$+Ts{W_xbD7Q5RbMDb&5UKiiYQHz~1`c#kqp8 zRyIhRw^p2&!ybqX*9LL;Rgl(g)+$zqVy$@daT3-~cqo~khZ0s*!|xFYo>`io9l>Ky zS-dE@kcAl=wmupLv45JtTLB;yk_S0fqJdHegEx9qX+}OUwS@CStC|&?u+cv}zJMb` zcH;4+pw#dKAy$f0v?G?A8=f!FBQ3bA&Z1o<@-4Pnn>n#De&DB@9tpL!G=yM=Ll3fy zoVC-qwc#lgqlE`Ga2&aSOxp5oEMFPxJCA2N$K_kw!rI=jf^$g$*bF!{t zF)aRY?rHnq(eQnQ+lUIIV#mt}rR&D3ZP<)tnHJS*MG#O}JGu74{@N8QU%dlfFU#_8 zRZWO{=;c}dt*T{oc%Z*E-`$b#!mYw=yQpfR6P?wI!{e=ZcAl5s8zOCw@)2dEw&Bh*CVlndR4RTc?H>7CMIM`IUNSK z&+z=h#PF1;p3#K8v#xkZ78!@qJdOu%`_9~oz96b!?^g^I#tL+rT@ck@)pT}9O`>{d zSdVrJMk=EEK~09oplvX>)#}NJ!na=lRoTq&6gtw3-4&}J*YrJ0Q;U-~cH>!!3fGe? z4p(!J(sXwd^BID33bA^n>3Zv?2d!Pjgin!MoTrohYBQ=lRVi6s9T2#MH z*V?ikOZga>8-WchvNF}OG=^dm)t6$WwJ5tIl}gR|Dh}Zh4dU1C6V@8+t`+)3jNcw$nn;63sfaeJDZe{f=H3Uj)WMY1H2KLONIw{XqxJzh?F4%#PzgGpT z+s`4FqWXuyTACp6`Y^Qw`*YtPe9sb$5=Hd~7rCo} z1W;7(NNdT!vxqdc;yLVb%H})_V5;x(0l;lIwInAW8}SDX(T}&aTP{+yO=MKSB+cSQ zQJBE{q;2x)(duKX6}okHTFzleh8$lu)hn$%op-}Hz)j%;SDU!;8pAyQ5{{Y zJlbV~K%KsSOw&?9lil>m$;FA@*?|I@0KKSpad5VIZf*(-3tAFjgGN-x)=`-9HTK@2 zY*r*!eU}8S&4U>2dzuGwT{wjt5XmYQJGEu^Dv^wP#MDDYGNEK7aGFB0TFFu2+|xxe zse~+X(J4*gba0WZQBr3x?Lq%Ii>8*WRl2q@=LN03B3TzCZxYFLkbIv=W?0U)1$i|& zh~(;j=aR|hP%_QqD0pYy5Xm)~3UclOu*PvSQ_p(Yx44Yfs<`cfSf?a36Lc2PDwScNIGNN)CNuo!SWZSknOXZoiw0+Rg_9^XoC4N^)T&Ez(Z zu5EsJylsAVP9(Q`J*l48_T5S$d(?If|hM>DQZZ-~Siq_V)4!j?G ze12w1BoBKPXwG2ST)fC6b;+x}O7hi)1+nWO)rUNsY7trAaw9Zb=&U+D^UIZ6}7t!TK zIA!Psb$dZ}1$Z&XycoT7y};vMpk2~lOxBC>G!!qgrwGZ7#tZ88g4{~WvjJUA-NVt#{*%+yo%55fcc~uK)hBbun&&Z$O-X{tz-59)m_!q)z!Dp?N$%WOGU{oJMqMP6#kFhy#rUtO`iQAj`6@?=XO!T|96TM z{qNf;eEz>%l+yp!t3(<7Z)>5j!L+p>tGXi1Hu&$f477HL45jd?H$KlVX9~$RE}|_| zrnBYnfT*B^miS&w3A`G?hlpKb2_-tWi7Yd)Q6)DpXOSB_#Zsp17B$kaThy`v#nwp+ zw(4n%1L@{yi{4FPVL;?5(TfT<&_;jDf%cZZzLu-RGD^0}?d7yhi>+<#2RaX95n%-x zx_aq2SIW&}w7rV9RaEmP+Saju*HYq$POYOSUQv17l_KOzULOJa%-D1Do?&-s4 zsG`*X?QMfS`wwAFO|)r-F}0J4iqf0|WN1Ag4)TARs)-KT#8>zISd>FfwY$#cloJVA zlV>U^eU!gl#cCQQtjHe=}8NtH9&eSn-#Sm*pfWXce{hZ*(E56t377Q9E&gLHeer=fa(&HyNO1Y=a-x$w4wVYa0YG85rkfD8$F5T0e#mQr*l4JbK1rcOJHV% z`k}M4VVl%BiFzjOZq#PA%#VyuC$YwC*3t2i(L~m`&FUT<86Tovl~mq!lF3&huTb)H z2R#*t+S%>q1S9{1)z`jZLAWW7;Sp-~FqW}S;wrvrhsoA8bar~)bgG|O(0*L?v>rjF zirQOtnoJZsqGf7?${QZlbMD&TT8y64lsW9Hhc7gl+s5%p%-k`oRgKQbqQ7CGM`k8) z`HI@^T_y)68l&{p&eRB&NTz0KDX{hv7Cvxle)7Z=VkTe#6l*AaYO)uZ{B7tvXFEFa z>a}wUD=73tTKh5!r%3}&kF3lS77#9l(GnXDRn&IuHpS992%ZkG+{I(#FD$49?;qwU z%tQaF`8i$>sl9m*<>V#kPCV*5S4!RcO{u_IhlWp$in?peY>4~AUhllX&S9htkkW5*_^|ZQMBZzq}uB*3JkdaAU`gKn$Gvc=LVm-}e zn$1Fe-P2_>*U5FdcsSRodq&~3Opju*=8y9v>YA)YVVJvUNUM9RYwX0_(5m~VtTkg~ zQIF?GXcERnp0QSq4K5$w_0cT1)`bm6&U)*fN(6P*C#^MOleM4L6zX1UtqD_&$EW6D zeV4Tyd~|&DdR@}*676X6jn--}Eg7-a!|ZOLC3&VzXKr*gpi|1q|Q|vTnSR9~_@MIXF3c!{o$ZGkzjNNd7;$ zCl#TFeJTH6OzrC2kKWYXf4sX(>)yYs;cp)Qu8zg3hT~{xF_i_vdem z5nE~Qs@(zd^+B{CeL|`0iTo`w97C0Aq($jy-gaIA5cwMmAm$Zo{;3#+?}^+^MSdt_ z6+O^}ClrpqlfOgS+i1!qdycNIx*qd;%Q>f9UPjN-xX3@ZoK^*LAwp{r@{P*qh+$nL zSv;r19y;dcPWRF4Q9R@1$Lz8R92n>g!LPU(+xmO-oj?C*B%h5fUc|N1`%|3)i*6I@ zHF3UXk##O`wWtm+@`sXv?IM4di-bL`slq8r*^%KTE@1WBCtO6ePZhu1QRk8xBCOPw z#nxHw-w%b>xsfA%UHZAN;Vb zb<{79q2%vC7c#x*l+R@iuZWW5d#lm#)w6y@({NKE=GD_v;ftJxn=o~@5Vb}TUJAX|1A#K4qNhc}YHNx`C7J5q7(wX$O~Vf(MtTP| zKO4TtYnZntWmKGtx8EQd-fcOFUGl_6FLXl zE*d^v2-_hVF0rP3ct+@)8l9t7S1U;kpK@V5Lg4w64hiSsNT+CMwkC!Y-$-3SqTy{8 zaAam&G;Fq}g)o>$mWDg5nLd#H^W*%UwBh%Oc0D<3SZ~c8Rn2)4*6?l%;NGpBK^m$p z&kmJ^2r}E*WRM>3u_!Pr8lH+1_~Eo;e2Ubw)SIO{o>`BvbUjnrss}eNBYPj6;(a`0{X+{6_-?fVov~dOV%uBz`xsOsKE$VI&tL7o0H>s znryg7(wv43_ck`ePtOfswwy%t&O(xM6=)c@mZS@isI6{Z89zUfvf6Jzmpy7NW=AW1 zi?wF0cSU_VQjTb-l#AE=Zm9K0|3FXoAROUay1H9hJMe{Vpg4h!uB$12bXFOBWY3e!+iFr|&l_%CXJ%~9gyKPK@w*kvzIYQ(Bc<#yH=J+w zNzW#F3h`sh-aa)vP2;A-!g1`5^_C?Qn ztL8H;7I<)Uj)xNIUDoh!3nII|P4!`+l@=dG!{UvmWV#=c4}e~+Tz0Ru@D_rY0;zWb z%Y5rzsNW#q6E3`OIw+RiQ3!13w+zeLc-@Q_Suk(FDv4MwU4i&)(AN-$2jC;#(%L>q zU!IEK###iyd6=< z+hsNQ4wFDT+S7HU8^y@AqxeB|Bma?Z>A2q~R`4Amp_l_*J-xkGi4}YsNWfd$!XkLo zPoUsBqt|i0J$(aW1rO{ABzU|?0xw%65b(N;-o6g*KZ0Pw*l6!-A=UB~Jl0nY;)BCJ zTCv27wJVR{vr+^x{o5ycNc-w~eQOab|Bf8mMfLEB-r@1C(W$YyQ)1;i$%c^1u>w}U z>z&B&Qz3O@gEM3Ot$0N-(2T5N)!IM0)@?~vNYq+p9#S##PvNnVvm~z`tVkx(uwG#7H1kpHE6t>FU#PGsJCZ z^?FKXs%i0`G=xsVb6>39Km}E>QLNtBiDlvJO89Bc$=zH)S-im8y>fnP9K!_)-NYu3 zw7Iz4?PB$2s>B{qNytuYvJQ?XQsa;sgU|lzEpOwYgK8G3mpMjNTQA)hDG^5@eZVeaB>4Ng!QMhY2AZvHDt)$q9EAnx{!$ zXVn*=8Yms$SKr*&hj;jcgE-po1;Pkh!ZgjeJy1de#A{1LBNejxmES?dmrxnl*A!Ms zNVtqNbmyT8hDkY2->WZ3M5$54>c6=TU|IUl@OQN-VPs-r60WrfK|M5!3CHT!j>A{q zz-NYsCoq!;;ae0u8wr7Z-iz{R>aujoIu#v9@QQrRtzX0rb0kqV2H)>BuS==3SU^EH zd!P|Atx}B=CfBv}|l2cF)o0=aUJTo*nK`+@$az6o_f~x5WJeA;$MTk5DyYH0^ zLzh~VQlccxv+7|=&f-41e-}X0Fi@buDE`>V5jY+y#|h7Sa1my~q0^3JKC*!{79r z)&h;{eWpI)oy4iiycT-Fsr$TlfGk*y6CLI>xdx;@=}{z7Um7PSaOn*WL*MXIY)+FI zi}>X2p1R-rM=&eMG(I9ypZ30wWD{pZt}*)FB=yhU&tU98d|9RUnfe0nH0>>#JVC;U zgOfuyh}0L^SmDVyv=|}gCU8}r9LC#GoSrXvx1o@%M)5ww0>8{)PJ@%sPc%6nWUx_z zBJ~xo6spPVy+y-x>20%^Uu9;qMnvjs-Xc(UdyAAfUg{yQ3Wj}Tz^H;#@~~GALkAh= z+3*M(dTDQiwCKvhk0SMTuN6G#ed;#T!knr1dM`v{1nIxT-wN4g3X|*5Vll1-)r1%Z zXXY`<%cefyeG~k0Ks@NDKIq-W%@`K@A#P)c#c74SIh8l{Veiezx)`4@b>YjVHc^(k z+uMV4TW<6|Q~%&mmxGBv=AuUYC|gR%q5>bM?qQQJ%49jIdp*+BT+*2OjCTu_C+jUz zpXDS9(}oAUHv>=04){6Qu;tgA7W=$xPMj3F7K8LW>Jp@>pZb2_Tp5+rPqSadANsAL ztFx3y@k=vHhe-WUk+KJ|{j^C}NWIS>O}0QP=BD4uJKlnp^SyMqV>wK$fVE<9P&e}k zo)eI72dpK7y&d>itWWs+k0TkRpO3%QPqr)GfXdb zaSQVgb|OPsWU0tc;I~fHySkE8ply<$$9a*emI;IRQ<=Dk&w(L!C-W zrqSFh@W0H}sU%ZPs8jh7q-yCAdz;AA$bL^L(y8Qo9%DP8Q%R{ZPLWO}Wkdg`F8FC| z@+BRJ5_&`vncTH7m6E*#PXy4Zq|MStD9tMb(5Yn0zmi4kRI=q)u=r_zM1DTxyWyI% zG^TCED=^+0HHfQIxeAc9DV<7cZkp+GtHFI?SU{(e8q7AbPUT-9D~25YOM3|kp-$!P zjNQS1Y3$StOQ(_w(PmqxlCo;M(W#`JX{)7ENqf*{SEur?(FqKqbSiBl9v9epz>8Qz zoyw?P>r|4x-qxw4L4EOHcY8PDmki z`j_a@P|qZnPJYEout?v<_OxZEr&(GmN#9+4Id+{b?;9PX@383WzVts-KY?O$qS|?%BDY7{c1ciH1P5PDZoetzy21ih8*k{klp+W zdYytH`4WMDX~6|$H@So)*-Zu@CnQUix|;p+;)Cp_*)i`lS$5Nql4UmyPC^9al-t?W z*?ze7Did20vYUljPz_MBn}$QnGKdscTz1pY&rNpI@Z++ZQH;-rtMmD^bqunAMA^+~ zNk-OCDs+VES{T1-qGUVlG-NlUuqmtO7(BvzjvW?|-88Hu*-e92BGt2WLALCs;S`tMG`z50@~Yh5-hs=ur_buzi>&isTz1ox z%H7*Y4=%QfU?`#YEs1jYVk6}yCA%3Zy|CEsJ@_eM6 z)mB{+WH(JA025?44X)LSOy6&^iq6yIG88$!;3j z0cH(3+Eo=7H@htYHyIJSLdBR=kJcky}rndtggRM= zH1H>6xAuM{F?&JT&7>pNWFFyo3=xpsEXFJ-yICw#vg~GJj)?4LK~7Y5Gl__SGeLIK zFbm3V8cHGAO~Xi*-86Wj?52SW%WfKuo~oji5@k0HvykkjVHB3#jB{v~KG;hiKErth z@qw(4!MBo#vL?xHnnEIAOm@>SlVmpyx{&Nhxo5&X)JW z*#%$O4ovGP*6GI?sj(1pBH)E!C~SU*(VRi?`Q<2HBA>tq_#*vXMwgf4T^9`4ot^c2 zxg9v*#t?LJexJef%3C8Lt!#UEa6gWJx>?UvaP!+Ul6#-3n z^P_}IDY-tmHd?rpYP6}`5iTXumIBAk!lhK%a!0td4i-_~1y3I(FuHz~hkB>6dLI=o zC3{7ARJe2rA0-vw2$zx>%l)=+DZLtNMBC75FIzyk^kP&iNWTDWSyo86l!_?{SE1C! z0pZep$l6d$j5HJ_sVU)Wxfr**v$e0MzvsY!fN&|XOQOQ1^crtPRJfF0wbZ;}SrbB6 z7ZEP44`p8xg-gGN14*KUA2C*Lloa|PR!eJUk5Mh_$!Sl@GK9c=e6Z}z7Zolwi2iyL z!llOO2$vdjM7T5pn6K&}Txu}21Bh>KPT5v1Txx7^c2(p~a@d1#slo8|Qi5=)!9#h{ zgQcNSo{kW?%^*p_rD3+HaH$L68xZongK(*_CkdBYXeeB2Y|snDNaqTd7DidP)WCdP z@e=MUHBMje92$!0S zYQ#dJ7#Uc!_|S5LYS-#>5iX@%_56BU373A43~}L7HuI=%u5t*MI%XwYYHY4>sj;I7 zzS1FFYK&~rU-VQjwE#=F)L8k#feN(#qOiKwV6Jd!k{u#o^+|RTE@iv=93{LtK)CdO z_{<~gi9See_O-C zrH+|StPw7?AaWORgiB+X6fTu!%y}H)Qj44|61)%sH4^u@ASpA3 z!lf=m>JGS-Y3>e{vFrl`Km1+;LfYqg~{MfE-xG{U8>J=DB}aH)%E zol8;O8UYf8OA|OT;Zm2AAYAGal7vfLMv`!;%h2c0ZPHGclq_88a_qC~7IuY8OcpM6 zIZj7$OY4p?lY~oMQrL)YQ9Uk8H>gYMbxFy>r8WoGsV+f{XMHwImxspX_0w;|3Bsi| z91||JK}WdM0+NJFZ8%Z5)FLDZmnNXDaA^WT3YRj#a}i6plqV?R6KqVl)O~u536~PQ z$_SUz12cq6@3;_8%utAzVuTNw}2$OW{)5lES5I z3x!K5rG!hF!osDrrG=a-C=sp^Py#QPq;M%ENVt?4BwQ*tFlUh)5H4j3giECX!li5= z;ZkWK;ZoX?!lkrDZ}(WZloBjlN*k7NDJ8XVDQ(kobtqg)1|?i7H>GeXZEN9D+SXE~ zYbjxbODSc9ODQFVOKD3Bm&$D=TxtNLQre~&#?($GN4S&>BwWh>rEn>2#)V58DW@e| zO6gFzloDFFl!;2Xl(uR8UI~{{(g>GYsZh9-Y_@P|1J3~+;Zieg*RvJ~ml`9@S@aYa z!led?3zxbWCJ9o%Efg*_xcdH`giB*aHQ|GBse!@@T)V~?E#XpQr0UX(FC|=R0R53N zgiDQ4)q}p>CgIW;5N3MP!e|XJ6fQMcXwQytsS8o1v~a0GBEqExu(e6=-W1y9;*Jf@ zZVtgtW8W?yTp9w=TtK&M4bg~jscU!S7$ID0(3o&3L&bzkJ#r6UK)BT66cjGCIE95v zEm9HTQj1kYxYS}55iYe@3ka7o)2vXk;-VHVH76Lo(iJW>5N^^D;ZlRegi8$+6)rVM zA>mTPhzXY(C`q`~phmdV*ph`y4W2AqYVc&?QiJ3C=+_jY_KAxO5H5vT!leeKbr46m z)If>Cr3CX5bb@fH$%@C|P`EU1W#Q7eSwHtcxYU42!leeK{n)~#F5(E6I*?Y`d|E9$ zyTYVlgfR%0(qyKgh;XUIX_+2%f$ohGE_L>%g-ab{Ot{oVWn2+kxHJim3YR8v^;BScEVrLNrwm%4T-bZUf44NA8mOSqH( z*+t{Rr4mC^EhJnj=eUK4;d`3gFH8q8BBQ+O2;ovwMHge?(j-s`mll9nxYS^_aH+A< z$kA-U<;QT)KVXP+*&42 z5H2-&l7veQN;TFC-4HHy0sZO=!ledqg-eay7A`eb{fwxDO9{XShUX$&$~~zFHSA0I z|6-~uTuMuTat15qC*#7UQHB;SjoP(jBF2MIxU>+5giE6sm8*qIV^~DEG>V5W`{`Rn z0pZdp!4iOcV+;)CBr8j!`Lu9p)J`iFcnwd&rBO)TDEZ~UtSwv`B}Royqqshy{9zk} zOQX0gTpGpTIzaLHAY7V^m{+V2E{#%L;Zh5AgiG08RJfEGa(Ou-TuQ3~4IxrUxRhBu zr;7`hT4l$DOP!3iIO(J1Zay1ZyvWI>I)y7-%DHuobo-ESX(GVFr4ADIw5EzAI}4XO zfYooGh-4vcW|6O2%zSw+Bf_QDSxyu#wQ>?pT7Brep>Sygb_6hA#-uE&MhcbQ|zi8*-ZG?GBRAG`C5DIhA?=rr{kHqSh$%5=cX@^+2GEs3;4UnmaU= zWU7CoHTlx-Zy;Ri(&-(PD_mL(Cvm-Zml=jFPfEh2$q40o$ik@I9N|)v&4F0Bv;fA! zr3O=So7C!RB?-c%4xAudYH-pgv4l$vpoB{ugL&M7aH)e>!lg-eJvoDLsex6^c>)UI zQUh@BwuDO!qOuS{W;<(ngjk?0TpG)5lu1drvBhC z;nH}mLy{3LU64d=b@R$|ps{eN;YBNbi?yDuD_uailndc^L+2n|YWAp0bx!F6*3xzY zfsU@Lsc0EWxRg1vg`IiBt?Nuo*9NaA^TB6fPy47g;cGz$yuZ zOX>7WuO>&D6ko8Aa4GZoTsf!~E-e7t!leZ$O1QKD8Wk=rKnsOS3*b@V(gL(lxU>Ln z3zrt4xWc6cNJhA{00FPdl7&l&Uy~?Y`a5W5);hwag6t{#+8MlN>NmOVxgiCiru(382E+z3u zPDq>VjBqKNAY7`-CE-%4 z#2%3)qyw8QjO0P{Pz#s77iTIv1cZL;;3hwY|3R9#p`4X1Tzb?7jBu$mJHn+>O3MhB z%5+?~l*Et1U6H^R>zPiIR??cmRj71~Fs)1v|r3&sla+p7$?(J_s z(neyw_+n0qcMS@!nc50v6ehJFZW{z~n<9==$iTr9P*Ni6cCxNcdzbVKpuY``AZG1| z@Gg~?7L-~kM3=W$T~#wO>dc_j^n}bJ4i;gNMkfc)Y!lvP>ruq&3h%(Xsi@hrlfpab zmeaxI)RNHdtnfN1l@=vMO5HBJL$k8fE^!2nk(1EfZku0?o1d^|HaOP@)3 zA0%n1Y%Qc^rLL{;K6C^}m8(59G zCG;0Ny!E@sh1hWY5EgK8oe1x%EXSEi{ZJLRaT0sNULIom-!B&80?Kh#m2(Zs@xJSw zg=y2T=}!vrd^c6%&t`(QEXUTDkZJ2?Y@}ZMo*TF9#YWc>Kz-QgtHj0-Hr|en=IgL= zzbg27vVJ0S42%f^z}R*M8@Hp}t=D6NirfA+Z2V5;d59`A;q7=3w%>rh<9=*3WU+BK zHuhp;XZ31%{2QMm#D(6KCG+@u+}lYzyMT&%pTb27McwBe#ooENYp4_|?xni8zo+85 z&r2$9yDIE^s<3@j*aO}>bzxu9h5bwyR#k<KFpgGdM6e3ac?hLjt}!TUD#)IVNXzDA5AQ5n-IIcs*tO%7UH=m z&45SD`8Kv*(2B3uj>!7mrLk5^Fzn5HCs9(4(iXKI_SXAN9R z*EQW>nM;+b(w1T__9t8<_t^nlq^v9hF90+uk<1w674m)+!?9f6C&IYI@23fE3QOe{c_pr$qrBa!^15e8i_&M3I8KX>I@_E^uI4O^!5@qRH)TJy<{j?;aOul3U1<`LMU3aB~ z$3@AP(9uyBRHP+8LHaEwEv4|W2eOr=>B!5{7xP~dOD>6ulKUTnbx}l=ye$1ySW{Y* zJhlIqT-fjMH|s+|xr#5dYFCsz)z$@QsTL(qwbP-9rAm}Mb%65t3@cIc)WLrPBQ2It zk;m{`BWi6?^3)+J&^F1>_)}L>t?0>ubG$tn*e5N^iTFMw83XA_(`Kz!3V40#Xp<#|7j}9(pS>BST6H|NG@H!6dp-)TPVP zH=tVe5V=K2q~inPA&5=Cv+NWqmFeBqF^!1k{=3RnVkby%m+5zNI-Tj=A=7toI-BX; zDbs(?>0GAwLYaOKryDc9yJY&koL--yS6+xvqmKA}WppN*Gu=0|&dvz`{hZvH=^q_y z#o>IQ?8QKLQ?d=o4|4KiO12~UAx>UO$pc7!n3I=L@*t9Ta&jLf`;q(zC--OC)sFAt zJ+)=pW}1b6H`lELiEYCF2Tt@Nv0eBd<-~C$b_o9-PF#b;F5%zHiBm{iB>azY;&i4D zfh7EYi90iWyM_O0-u_soZ;$Xl!`t^~`nKU{KFf(OAc3QKfD;cPfus2xC%%mY zj^^{6_#qPbJmjA_@lzx&6#f@D@$*dII4bi+PCS*n7mtWp;pLBF?mj(3lGU@cw(tLI z*?%*VDwhbg?+jwW`aj}~xBF5?BQ*aTo8RM?cMZ+X?VrJ?*r%YPLVJ3GkvnbVz|8a{ zV?So>V-gFmCYA9g4Bj6B!@NIb_zQ>-#cK4TG)IF;O2rYNAuFZg2+#nR(s2ZcRHEYu zq*Tm+*W8H?S(cv1-&7b!K-${CuT^^MVaR|VFrDs|8VW-O5TuPJWB^&0(BQfZs@*lh z&*C3gR>%MXl!b4sWmhVT9WsFKc_7¼Og(^yi-06D7Z8{#l~8dAsrWml_^`kq>L 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䧪@ZrRub7gUfTwsCel$dhx}jpzGtXn3xG)5{>8TTh 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 F{};!nCjI~b literal 0 HcmV?d00001 diff --git a/src-archiver/net/sf/jremoterun/utilities/nonjdk/archiver/JrrCommonsArchiver.groovy b/src-archiver/net/sf/jremoterun/utilities/nonjdk/archiver/JrrCommonsArchiver.groovy new file mode 100644 index 00000000..3efc6777 --- /dev/null +++ b/src-archiver/net/sf/jremoterun/utilities/nonjdk/archiver/JrrCommonsArchiver.groovy @@ -0,0 +1,149 @@ +package net.sf.jremoterun.utilities.nonjdk.archiver + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.commons.compress.archivers.ArchiveEntry +import org.apache.commons.compress.archivers.ArchiveOutputStream +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream +import org.rauschig.jarchivelib.ArchiveFormat +import org.rauschig.jarchivelib.CommonsArchiverOriginal +import org.rauschig.jarchivelib.IOUtils; + +import java.util.logging.Logger; + +@CompileStatic +class JrrCommonsArchiver extends CommonsArchiverOriginal { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public int maxErrorFiles = 10; + public long processedFiles = 0; + public long uncompressedFileSize = 0; + public boolean removeArchiveOnError = true; + public boolean checkOnZeroFiles = true; + public List errorFiles = [] + public List ignoreFiles = [] + // path separator is / + public List ignoreFilesFiles = [] + public List ignoreFilesPattern = [] + public List ignoreFilesStartWithPattern = [] + public File destinationFile; + public volatile File lastFile; + public volatile boolean needStop = false; + + JrrCommonsArchiver(ArchiveFormat archiveFormat) { + super(archiveFormat) + } + + + @Override + File create(String archive, File destinationDir, File... sources) throws IOException { + try { + File result = super.create(archive, destinationDir, sources) + if (checkOnZeroFiles && processedFiles == 0) { + throw new Exception('No files in archive') + } + return result; + } catch (Throwable e) { + if (removeArchiveOnError && destinationFile != null) { + destinationFile.delete() + } + throw e; + } + } + + @Override + protected File createNewArchiveFile(String archive, String extension, File destination) throws IOException { + destinationFile = super.createNewArchiveFile(archive, extension, destination) + return destinationFile; + } + + @Override + protected ArchiveOutputStream createArchiveOutputStream(File archiveFile) throws IOException { + return super.createArchiveOutputStream(archiveFile) + } + + protected static TarArchiveOutputStream createArchiveOutputStreamTarBig(File archiveFile) throws IOException { + TarArchiveOutputStream archiveOutputStream = new TarArchiveOutputStream(new FileOutputStream(archiveFile)); + archiveOutputStream.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX); + archiveOutputStream.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); + return archiveOutputStream; + } + + @Override + protected void writeToArchive(File parent, File[] sources, ArchiveOutputStream archive) throws IOException { + if(needStop){ + throw new Exception('stop requested') + } + for (File source : sources) { + lastFile = source; + String relativePath = IOUtils.relativePath(parent, source); + boolean needed = isNeedWriteFile(source, relativePath, archive) + if (needed) { + createArchiveEntry(source, relativePath, archive); + if (source.isDirectory()) { + File[] files = source.listFiles() + writeToArchive(parent, files, archive); + } + } + } + } + + boolean isNeedWriteFile(File file, String relativePath, ArchiveOutputStream archive) { + boolean needAccept = true + if(ignoreFilesFiles.contains(file)){ + needAccept = false + } + if(needAccept) { + relativePath = relativePath.replace('\\', '/') + String findIgnore1 = ignoreFilesPattern.find { relativePath.contains(it) } + needAccept = findIgnore1 == null; + if (needAccept) { + String findIgnore2 = ignoreFilesStartWithPattern.find { relativePath.startsWith(it) } + needAccept = findIgnore2 == null + } + } + if (!needAccept) { + ignoreFiles.add(file); + log.info "ignoring : ${relativePath} ${file}" + } + return needAccept; + } + + @Override + protected void createArchiveEntry(File file, String entryName, ArchiveOutputStream archive) throws IOException { + if(needStop){ + throw new Exception('stop requested') + } + lastFile = file; + ArchiveEntry entry = archive.createArchiveEntry(file, entryName); + // TODO #23: read permission from file, write it to the ArchiveEntry + archive.putArchiveEntry(entry); + + if (!entry.isDirectory()) { + FileInputStream input = null; + try { + input = new FileInputStream(file); + uncompressedFileSize += IOUtils.copy(input, archive); + processedFiles++; + } catch (Throwable e) { + //TODO write dummy bytes, so number of written bytes matches file size + onError(e, file, entryName, archive) + } finally { + IOUtils.closeQuietly(input); + } + + } + + archive.closeArchiveEntry(); + } + + + void onError(Throwable e, File file, String entryName, ArchiveOutputStream archive) { + log.info("${entryName} ${file}", e) + if (errorFiles.size() > maxErrorFiles) { + throw e + } + errorFiles.add(file); + } + +} diff --git a/src-archiver/org/rauschig/jarchivelib/CommonsArchiverOriginal.groovy b/src-archiver/org/rauschig/jarchivelib/CommonsArchiverOriginal.groovy new file mode 100644 index 00000000..e2f211d0 --- /dev/null +++ b/src-archiver/org/rauschig/jarchivelib/CommonsArchiverOriginal.groovy @@ -0,0 +1,92 @@ +package org.rauschig.jarchivelib + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.commons.compress.archivers.ArchiveInputStream +import org.apache.commons.compress.archivers.ArchiveOutputStream; + +import java.util.logging.Logger; + +@CompileStatic +public class CommonsArchiverOriginal extends CommonsArchiver{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public CommonsArchiverOriginal(ArchiveFormat archiveFormat) { + super(archiveFormat) + } + + @Override + File create(String archive, File destination, File... sources) throws IOException { + return super.create(archive, destination, sources) + } + + @Override + File create(String archive, File destination, File source) throws IOException { + return super.create(archive, destination, source) + } + + @Override + ArchiveFormat getArchiveFormat() { + return super.getArchiveFormat() + } + + @Override + void extract(File archive, File destination) throws IOException { + super.extract(archive, destination) + } + + @Override + void extract(InputStream archive, File destination) throws IOException { + super.extract(archive, destination) + } + + @Override + ArchiveStream stream(File archive) throws IOException { + return super.stream(archive) + } + + @Override + String getFilenameExtension() { + return super.getFilenameExtension() + } + + @Override + protected File createNewArchiveFile(String archive, String extension, File destination) throws IOException { + return super.createNewArchiveFile(archive, extension, destination) + } + + @Override + protected ArchiveInputStream createArchiveInputStream(File archive) throws IOException { + return super.createArchiveInputStream(archive) + } + + @Override + protected ArchiveInputStream createArchiveInputStream(InputStream archive) throws IOException { + return super.createArchiveInputStream(archive) + } + + @Override + protected ArchiveOutputStream createArchiveOutputStream(File archiveFile) throws IOException { + return super.createArchiveOutputStream(archiveFile) + } + + @Override + protected void assertExtractSource(File archive) throws FileNotFoundException, IllegalArgumentException { + super.assertExtractSource(archive) + } + + @Override + protected void writeToArchive(File[] sources, ArchiveOutputStream archive) throws IOException { + super.writeToArchive(sources, archive) + } + + @Override + protected void writeToArchive(File parent, File[] sources, ArchiveOutputStream archive) throws IOException { + super.writeToArchive(parent, sources, archive) + } + + @Override + protected void createArchiveEntry(File file, String entryName, ArchiveOutputStream archive) throws IOException { + super.createArchiveEntry(file, entryName, archive) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/javassist/ClassRedefintions.groovy b/src-common/net/sf/jremoterun/utilities/javassist/ClassRedefintions.groovy deleted file mode 100644 index 7ae052bb..00000000 --- a/src-common/net/sf/jremoterun/utilities/javassist/ClassRedefintions.groovy +++ /dev/null @@ -1,90 +0,0 @@ -package net.sf.jremoterun.utilities.javassist - -import groovy.transform.CompileStatic -import javassist.* -import javassist.runtime.Desc -import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.JrrUtilities - -import java.util.logging.Logger - -import static net.sf.jremoterun.utilities.javassist.JrrJavassistUtils.* - -@Deprecated -@CompileStatic -public class ClassRedefintions { - - private static final Logger log = Logger.getLogger(JrrClassUtils.getCurrentClass().getName()); - - - private static volatile boolean initDone = false; - - static void init() throws Exception { - if (!initDone) { - initDone = true; - ClassPool.doPruning = false; - Desc.useContextClassLoader = true; - final ClassPool pool = ClassPool.getDefault(); - final ClassPath classPath = new ClassClassPath(JrrClassUtils.getCurrentClass()); - pool.appendClassPath(classPath); - } - } - - - public static void redifineSecurityManager() throws Exception { - init(); - Class clazz = java.lang.System - final CtClass cc = JrrJavassistUtils.getClassFromDefaultPool(clazz); - CtBehavior method1 = JrrJavassistUtils.findMethod(clazz, cc, "setSecurityManager", 1); - - method1.setBody("{setSecurityManager0(null);}"); - JrrJavassistUtils.redefineClass(cc, clazz); - } - - - static void redifineSocketClass() throws Exception { - init(); - Class clazz = Socket - final CtClass cc = getClassFromDefaultPool(clazz); - CtBehavior intiMethod = JrrJavassistUtils.findConstructor(cc, 2) - intiMethod.insertBefore("\$2=446;"); - final CtBehavior connectMethod = findMethod(clazz, cc, "connect", 2); - connectMethod.insertBefore(""" - ${createLogVar} - ${LogVarName2}.info(\$1.toString()); - """); - connectMethod.insertAfter(""" - ${createLogVar} - ${LogVarName2}.info(\$1.toString()+" connect ok"); - """) - JrrJavassistUtils.redefineClass(cc, clazz); - } - - - static void redifineHttpsCertificateCheck1() throws Exception { - init(); - Class class1 = JrrUtilities.getCurrentClassLoader().loadClass("sun.net.www.protocol.https.HttpsClient"); - final CtClass cc = getClassFromDefaultPool(class1); - final CtMethod method = cc.getDeclaredMethod("checkURLSpoofing"); - method.setBody("{}"); - JrrJavassistUtils.redefineClass(cc, class1); - } - - - static void redifineClassLoader() throws Exception { - init(); - Class class1 = ClassLoader - final CtClass cc = getClassFromDefaultPool(class1); - CtBehavior method1; - try { - method1 = findMethod(class1, cc, "checkCerts", 2); - } catch (NoSuchMethodException e) { - log.info("failed find checkCerts method ${e}"); - return; - } - method1.setBody("{}"); - redefineClass(cc, class1); - } - - -} diff --git a/src-common/net/sf/jremoterun/utilities/javassist/JrrJavassistUtils.groovy b/src-common/net/sf/jremoterun/utilities/javassist/JrrJavassistUtils.groovy index e590d61c..06152bda 100644 --- a/src-common/net/sf/jremoterun/utilities/javassist/JrrJavassistUtils.groovy +++ b/src-common/net/sf/jremoterun/utilities/javassist/JrrJavassistUtils.groovy @@ -4,6 +4,7 @@ import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.UrlToFileConverter import net.sf.jremoterun.utilities.classpath.ClRef +import javax.management.ObjectName import java.io.File import java.lang.instrument.ClassDefinition; import java.net.MalformedURLException; @@ -38,6 +39,7 @@ public class JrrJavassistUtils { public static String constrMethod = ''; public static String LogVarName = '$log' + public static String mapVarName = '$map12' // following can be used in groovy code, without escaping public static String LogVarName2 = 'jrrlog' @@ -48,7 +50,19 @@ public class JrrJavassistUtils { java.util.logging.Logger ${LogVarName2} = ${LogVarName}; """ - + public static String createGlobalServicesMapVar = + ''' +java.util.Map $map12; +try { + $map12 = (java.util.Map) java.lang.management.ManagementFactory.getPlatformMBeanServer().getAttribute(new javax.management.ObjectName("JRemoteRun:type=Runner"), "SharedObjects"); +}catch(Exception e){ + throw new RuntimeException(e); +} + + +''' + + public static volatile boolean initDone = false; public static void init() throws Exception { @@ -98,7 +112,7 @@ public class JrrJavassistUtils { } - public static CtMethod findMethodG(final CtClass cc, + static CtMethod findMethodG(final CtClass cc, @ClosureParams(value=SimpleType.class, options="javassist.CtMethod") Closure matcher) throws NoSuchMethodException, NotFoundException { @@ -112,7 +126,7 @@ public class JrrJavassistUtils { } - public static CtMethod findMethod(final Class clazz ,final CtClass cc, final String methodName, final int numberParams) + static CtMethod findMethod(final Class clazz ,final CtClass cc, final String methodName, final int numberParams) throws NoSuchMethodException, NotFoundException { if(!clazz.getName().equals(cc.getName())) { throw new IllegalArgumentException("class names mismacthes : "+clazz.getName()+" , "+cc.getName()); @@ -154,9 +168,25 @@ public class JrrJavassistUtils { } throw new NoSuchMethodException(cc.getName() + ", params count: "+numberParams); } + + static void appendForEachConstructorThreadDump(ClRef clazz){ + Class clazz1 = clazz.loadClass2() + appendForEachConstructorThreadDump(clazz1) + } + + static void appendForEachConstructorThreadDump(Class clazz){ + appendForEachConstructor(clazz,'{Thread.dumpStack();}') + } + + static void appendForEachConstructor(Class clazz,String code){ + CtClass ctClass = getClassFromDefaultPool(clazz); + ctClass.getConstructors().toList().each { + it.insertAfter(code); + } + redefineClass(ctClass,clazz); + } - - public static CtConstructor findConstructorG(final CtClass cc, + static CtConstructor findConstructorG(final CtClass cc, @ClosureParams(value=SimpleType.class, options="javassist.CtConstructor") Closure matcher) throws NoSuchMethodException, NotFoundException { @@ -220,7 +250,11 @@ public class JrrJavassistUtils { public static List getRelatedClasses2(final Class class1) throws Exception { final ClassLoader classLoader = class1.getClassLoader(); - File file = UrlToFileConverter.c.convert(JrrUtils.getClassFileLocation(class1)); + URL url77=JrrUtils.getClassFileLocation(class1); + if(url77==null){ + throw new Exception("failed detect url for class : "+class1.getName()) + } + File file = UrlToFileConverter.c.convert(url77); JrrUtilities.checkFileExist(file) String prefix = getBaseName(file); List childs = [] @@ -255,13 +289,13 @@ public class JrrJavassistUtils { } - public static void redefineClass(final CtClass class2, Class class1) + public static void redefineClass(final CtClass ctClass, Class class1) throws Exception { - assert class2.name == class1.name - final ClassDefinition classDefinition = new ClassDefinition(class1, class2.toBytecode()); - if (class2.isFrozen()) { - log.info("defrost " + class2.getName()); - class2.defrost(); + assert ctClass.name == class1.name + final ClassDefinition classDefinition = new ClassDefinition(class1, ctClass.toBytecode()); + if (ctClass.isFrozen()) { + log.info("defrost " + ctClass.getName()); + ctClass.defrost(); } final ClassDefinition[] classDefinitions = [ classDefinition ]; if (SimpleJvmTiAgent.instrumentation == null) { diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/BaseDirSetting.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/BaseDirSetting.groovy new file mode 100644 index 00000000..32b34bb9 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/BaseDirSetting.groovy @@ -0,0 +1,30 @@ +package net.sf.jremoterun.utilities.nonjdk + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ZeroOverheadFileRef; + +import java.util.logging.Logger; + +@CompileStatic +enum BaseDirSetting implements ToFileRef2, ChildFileLazy, ZeroOverheadFileRef{ + + baseDirSetting, + ; + + public File baseDir = new File(MavenDefaultSettings.mavenDefaultSettings.userHome, "jrr/"); + + @Override + File resolveToFile() { + return baseDir; + } + + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this,child) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/ConsoleRedirect.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/ConsoleRedirect.groovy index f82e5081..8224d819 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/ConsoleRedirect.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/ConsoleRedirect.groovy @@ -21,16 +21,18 @@ class ConsoleRedirect { public static volatile Exception creationCallStack; - static void setOutputWithRotationAndFormatter(File outFile, int maxDepth) { - setOutputWithRotation(outFile, maxDepth) + static FileOutputStream2 setOutputWithRotationAndFormatter(File outFile, int maxDepth) { + FileOutputStream2 outputStream2 = setOutputWithRotation(outFile, maxDepth) JdkLogFormatter.setLogFormatter() + return outputStream2 } - static void setOutputWithRotation(File outFile, int maxDepth) { + static FileOutputStream2 setOutputWithRotation(File outFile, int maxDepth) { SetConsoleOut2.setConsoleOutIfNotInited() FileRotate.rotateFile(outFile, maxDepth) - setOutputToConsoleAndFile(outFile) + FileOutputStream2 outputStream2 = setOutputToConsoleAndFile(outFile) setOutputForConsleHandler(SetConsoleOut2.proxyOut) + return outputStream2 } static void setOutputForConsleHandler(OutputStream outputStream) { @@ -41,24 +43,25 @@ class ConsoleRedirect { } } - static void setOutputToConsoleAndFile(File out) { - setOutputToConsoleAndFile3(out) + static FileOutputStream2 setOutputToConsoleAndFile(File out) { + return setOutputToConsoleAndFile3(out) } - static void setOutputToConsoleAndFile3(File out) { + static FileOutputStream2 setOutputToConsoleAndFile3(File out) { if (outputFile != null) { log.warn("Output redirection was set before in ", creationCallStack) throw new IllegalStateException("Output redirection was set before : ${outputFile}") } - setOutputToConsoleAndFileImpl(out) + return setOutputToConsoleAndFileImpl(out) } - static void setOutputToConsoleAndFileImpl(File out) { + static FileOutputStream2 setOutputToConsoleAndFileImpl(File out) { JrrUtilities3.checkFileExist(out.parentFile) FileOutputStream2 out2 = new FileOutputStream2(out, false); RedirectOutStream.addOutStream out2 outputFile = out creationCallStack = new Exception("Creation call stack") + return out2; } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/ConsoleTextFunctionPrefix.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/ConsoleTextFunctionPrefix.groovy new file mode 100644 index 00000000..36b7985e --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/ConsoleTextFunctionPrefix.groovy @@ -0,0 +1,17 @@ +package net.sf.jremoterun.utilities.nonjdk + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ConsoleTextFunctionPrefix { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static String functionWord = 'TextFunction : '; + + public static String ignoreWord = 'ignore '; + + public static List ignoreWords = [ignoreWord, 'echo ']; + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/FileEnumContains.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/FileEnumContains.groovy new file mode 100644 index 00000000..8d1db8c7 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/FileEnumContains.groovy @@ -0,0 +1,13 @@ +package net.sf.jremoterun.utilities.nonjdk + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +interface FileEnumContains { + + + File getFile() + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/FileRotate.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/FileRotate.groovy index fe43d5f5..41adcb31 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/FileRotate.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/FileRotate.groovy @@ -1,32 +1,55 @@ package net.sf.jremoterun.utilities.nonjdk; import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils import org.apache.commons.io.FileUtils import java.text.DecimalFormat +import java.util.logging.Logger @CompileStatic class FileRotate { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static boolean copyIfFailedRenameG = true; + public static boolean doSync = true; + static void rotateFile(File file, File archiveRotationDir, int maxDepth) { if (file.exists()) { - file = file.absoluteFile.canonicalFile - rotateFileImpl(file, archiveRotationDir, 0, maxDepth,true) + file = file.getAbsoluteFile().getCanonicalFile() + rotateFileImplSync(file, archiveRotationDir, 0, maxDepth, true, copyIfFailedRenameG) } } static void rotateFile(File file, int maxDepth) { if (file.exists()) { - file = file.absoluteFile.canonicalFile - rotateFileImpl(file, 0, maxDepth) + if (file.isFile() && file.length() == 0) { + + } else { + file = file.getAbsoluteFile().getCanonicalFile() + rotateFileImpl(file, 0, maxDepth) + } } } static void rotateFileImpl(File file, int depth, int maxDepth) { - rotateFileImpl(file, file.parentFile, depth, maxDepth,true); + rotateFileImplSync(file, file.parentFile, depth, maxDepth, true, copyIfFailedRenameG); + } + + + static void rotateFileImplSync(File file, File archiveRotationDir, int depth, int maxDepth, boolean doRenameOrCopy, boolean copyIfFailedRename) { + if (doSync) { + String syncOnObject = file.getAbsoluteFile().getCanonicalFile().getAbsolutePath().intern() + synchronized (syncOnObject) { + rotateFileImpl(file, archiveRotationDir, depth, maxDepth, doRenameOrCopy, copyIfFailedRename) + } + } else { + rotateFileImpl(file, archiveRotationDir, depth, maxDepth, doRenameOrCopy, copyIfFailedRename) + } } - static void rotateFileImpl(File file, File archiveRotationDir, int depth, int maxDepth,boolean doRenameOrCopy) { + static void rotateFileImpl(File file, File archiveRotationDir, int depth, int maxDepth, boolean doRenameOrCopy, boolean copyIfFailedRename) { int newDepth = depth + 1 DecimalFormat df = new DecimalFormat("00"); String dirPrefix = "${file.name}.${df.format(depth)}" @@ -42,14 +65,32 @@ class FileRotate { } assert !file2.exists() } else { - rotateFileImpl(file, archiveRotationDir, newDepth, maxDepth,true); + rotateFileImpl(file, archiveRotationDir, newDepth, maxDepth, true, copyIfFailedRename); + assert !file2.exists() } } assert !file2.exists() - if(doRenameOrCopy) { - assert fileFrom.renameTo(file2) - }else{ - FileUtils.copyFile(file,file2) + if (doRenameOrCopy) { + boolean renameDone = fileFrom.renameTo(file2) + if (!renameDone) { + if (copyIfFailedRename) { + log.info "Failed rename ${fileFrom} to ${file2}, do coping .." + if(fileFrom.isDirectory()){ + FileUtilsJrr.copyDirectory(fileFrom, file2); + FileUtils.deleteQuietly(fileFrom ) + }else { + FileUtilsJrr.copyFile(fileFrom, file2); + fileFrom.delete() + } +// if(fileFrom.exists()){ +// throw new Exception("Failed delete file : ${fileFrom}") +// } + } else { + throw new IOException("Failed rename ${fileFrom} to ${file2}") + } + } + } else { + FileUtilsJrr.copyFile(file, file2) } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/FileUtilsJrr.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/FileUtilsJrr.groovy new file mode 100644 index 00000000..79799843 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/FileUtilsJrr.groovy @@ -0,0 +1,644 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.jremoterun.utilities.nonjdk + + +import org.apache.commons.io.IOUtils +import org.apache.commons.io.filefilter.* + +import java.nio.channels.FileChannel + +/** + * General file manipulation utilities. + *

+ * Facilities are provided in the following areas: + *

+ *

+ * Note that a specific charset should be specified whenever possible. + * Relying on the platform default means that the code is Locale-dependent. + * Only use the default if the files are known to always use the platform default. + *

+ * Origin of code: Excalibur, Alexandria, Commons-Utils + * + */ +public class FileUtilsJrr { + + + /** + * The file copy buffer size (30 MB) + */ + private static final long FILE_COPY_BUFFER_SIZE = 1024 * 1024 * 30; + + + + + //----------------------------------------------------------------------- + /** + * Copies a file to a directory preserving the file date. + *

+ * This method copies the contents of the specified source file + * to a file of the same name in the specified destination directory. + * The destination directory is created if it does not exist. + * If the destination file exists, then this method will overwrite it. + *

+ * Note: This method tries to preserve the file's last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that the operation will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcFile an existing file to copy, must not be {@code null} + * @param destDir the directory to place the copy in, must not be {@code null} + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFile(File, File, boolean) + */ + public static void copyFileToDirectory(final File srcFile, final File destDir) throws IOException { + copyFileToDirectory(srcFile, destDir, true); + } + + /** + * Copies a file to a directory optionally preserving the file date. + *

+ * This method copies the contents of the specified source file + * to a file of the same name in the specified destination directory. + * The destination directory is created if it does not exist. + * If the destination file exists, then this method will overwrite it. + *

+ * Note: Setting preserveFileDate to + * {@code true} tries to preserve the file's last modified + * date/times using {@link File#setLastModified(long)}, however it is + * not guaranteed that the operation will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcFile an existing file to copy, must not be {@code null} + * @param destDir the directory to place the copy in, must not be {@code null} + * @param preserveFileDate true if the file date of the copy + * should be the same as the original + * + * @throws NullPointerException if source or destination is {@code null} + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @throws IOException if the output file length is not the same as the input file length after the copy + * completes + * @see #copyFile(File, File, boolean) + * @since 1.3 + */ + public static void copyFileToDirectory(final File srcFile, final File destDir, final boolean preserveFileDate) + throws IOException { + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (destDir.exists() && destDir.isDirectory() == false) { + throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory"); + } + final File destFile = new File(destDir, srcFile.getName()); + copyFile(srcFile, destFile, preserveFileDate); + } + + /** + * Copies a file to a new location preserving the file date. + *

+ * This method copies the contents of the specified source file to the + * specified destination file. The directory holding the destination file is + * created if it does not exist. If the destination file exists, then this + * method will overwrite it. + *

+ * Note: This method tries to preserve the file's last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that the operation will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcFile an existing file to copy, must not be {@code null} + * @param destFile the new file, must not be {@code null} + * + * @throws NullPointerException if source or destination is {@code null} + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @throws IOException if the output file length is not the same as the input file length after the copy + * completes + * @see #copyFileToDirectory(File, File) + * @see #copyFile(File, File, boolean) + */ + public static void copyFile(final File srcFile, final File destFile) throws IOException { + copyFile(srcFile, destFile, true); + } + + /** + * Copies a file to a new location. + *

+ * This method copies the contents of the specified source file + * to the specified destination file. + * The directory holding the destination file is created if it does not exist. + * If the destination file exists, then this method will overwrite it. + *

+ * Note: Setting preserveFileDate to + * {@code true} tries to preserve the file's last modified + * date/times using {@link File#setLastModified(long)}, however it is + * not guaranteed that the operation will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcFile an existing file to copy, must not be {@code null} + * @param destFile the new file, must not be {@code null} + * @param preserveFileDate true if the file date of the copy + * should be the same as the original + * + * @throws NullPointerException if source or destination is {@code null} + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @throws IOException if the output file length is not the same as the input file length after the copy + * completes + * @see #copyFileToDirectory(File, File, boolean) + * @see #doCopyFile(File, File, boolean) + */ + public static void copyFile(final File srcFile, final File destFile, + final boolean preserveFileDate) throws IOException { + checkFileRequirements(srcFile, destFile); + if (srcFile.isDirectory()) { + throw new IOException("Source '" + srcFile + "' exists but is a directory"); + } + if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) { + throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same"); + } + final File parentFile = destFile.getParentFile(); + if (parentFile != null) { + if (!parentFile.mkdirs() && !parentFile.isDirectory()) { + throw new IOException("Destination '" + parentFile + "' directory cannot be created"); + } + } + if (destFile.exists() && destFile.canWrite() == false) { + throw new IOException("Destination '" + destFile + "' exists but is read-only"); + } + doCopyFile(srcFile, destFile, preserveFileDate); + } + + /** + * Copy bytes from a File to an OutputStream. + *

+ * This method buffers the input internally, so there is no need to use a BufferedInputStream. + *

+ * + * @param input the File to read from + * @param output the OutputStream to write to + * @return the number of bytes copied + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since 2.1 + */ + public static long copyFile(final File input, final OutputStream output) throws IOException { + FileInputStream fis = new FileInputStream(input) + try { + return IOUtils.copyLarge(fis, output); + } finally { + fis.close() + } + + } + + /** + * Internal copy file method. + * This caches the original file length, and throws an IOException + * if the output file length is different from the current input file length. + * So it may fail if the file changes size. + * It may also fail with "IllegalArgumentException: Negative size" if the input file is truncated part way + * through copying the data and the new file size is less than the current position. + * + * @param srcFile the validated source file, must not be {@code null} + * @param destFile the validated destination file, must not be {@code null} + * @param preserveFileDate whether to preserve the file date + * @throws IOException if an error occurs + * @throws IOException if the output file length is not the same as the input file length after the + * copy completes + * @throws IllegalArgumentException "Negative size" if the file is truncated so that the size is less than the + * position + */ + private static void doCopyFile(final File srcFile, final File destFile, final boolean preserveFileDate) + throws IOException { + if (destFile.exists() && destFile.isDirectory()) { + throw new IOException("Destination '" + destFile + "' exists but is a directory"); + } + FileInputStream fis; + FileChannel input; + FileOutputStream fos; + FileChannel output + try { + fis = new FileInputStream(srcFile); + input = fis.getChannel(); + fos = new FileOutputStream(destFile); + output = fos.getChannel() + + final long size = input.size(); // TODO See IO-386 + long pos = 0; + long count = 0; + while (pos < size) { + final long remain = size - pos; + count = remain > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : remain; + final long bytesCopied = output.transferFrom(input, pos, count); + if (bytesCopied == 0) { // IO-385 - can happen if file is truncated after caching the size + break; // ensure we don't loop forever + } + pos += bytesCopied; + } + } finally { + if (fis != null) { + fis.close() + } + if (fos != null) { + fos.close() + } + } + + final long srcLen = srcFile.length(); // TODO See IO-386 + final long dstLen = destFile.length(); // TODO See IO-386 + if (srcLen != dstLen) { + throw new IOException("Failed to copy full contents from '" + + srcFile + "' to '" + destFile + "' Expected length: " + srcLen + " Actual: " + dstLen); + } + if (preserveFileDate) { + destFile.setLastModified(srcFile.lastModified()); + } + } + + //----------------------------------------------------------------------- + /** + * Copies a directory to within another directory preserving the file dates. + *

+ * This method copies the source directory and all its contents to a + * directory of the same name in the specified destination directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: This method tries to preserve the files' last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcDir an existing directory to copy, must not be {@code null} + * @param destDir the directory to place the copy in, must not be {@code null} + * + * @throws NullPointerException if source or destination is {@code null} + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since 1.2 + */ + public static void copyDirectoryToDirectory(final File srcDir, final File destDir) throws IOException { + if (srcDir == null) { + throw new NullPointerException("Source must not be null"); + } + if (srcDir.exists() && srcDir.isDirectory() == false) { + throw new IllegalArgumentException("Source '" + destDir + "' is not a directory"); + } + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (destDir.exists() && destDir.isDirectory() == false) { + throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory"); + } + copyDirectory(srcDir, new File(destDir, srcDir.getName()), true); + } + + /** + * Copies a whole directory to a new location preserving the file dates. + *

+ * This method copies the specified directory and all its child + * directories and files to the specified destination. + * The destination is the new location and name of the directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: This method tries to preserve the files' last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcDir an existing directory to copy, must not be {@code null} + * @param destDir the new directory, must not be {@code null} + * + * @throws NullPointerException if source or destination is {@code null} + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since 1.1 + */ + public static void copyDirectory(final File srcDir, final File destDir) throws IOException { + copyDirectory(srcDir, destDir, true); + } + + /** + * Copies a whole directory to a new location. + *

+ * This method copies the contents of the specified source directory + * to within the specified destination directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: Setting preserveFileDate to + * {@code true} tries to preserve the files' last modified + * date/times using {@link File#setLastModified(long)}, however it is + * not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcDir an existing directory to copy, must not be {@code null} + * @param destDir the new directory, must not be {@code null} + * @param preserveFileDate true if the file date of the copy + * should be the same as the original + * + * @throws NullPointerException if source or destination is {@code null} + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since 1.1 + */ + public static void copyDirectory(final File srcDir, final File destDir, + final boolean preserveFileDate) throws IOException { + copyDirectory(srcDir, destDir, null, preserveFileDate); + } + + /** + * Copies a filtered directory to a new location preserving the file dates. + *

+ * This method copies the contents of the specified source directory + * to within the specified destination directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: This method tries to preserve the files' last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + *

+ *

Example: Copy directories only

+ *
+     *  // only copy the directory structure
+     *  FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY);
+     *  
+ * + *

Example: Copy directories and txt files

+ *
+     *  // Create a filter for ".txt" files
+     *  IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
+     *  IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
+     *
+     *  // Create a filter for either directories or ".txt" files
+     *  FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
+     *
+     *  // Copy using the filter
+     *  FileUtils.copyDirectory(srcDir, destDir, filter);
+     *  
+ * + * @param srcDir an existing directory to copy, must not be {@code null} + * @param destDir the new directory, must not be {@code null} + * @param filter the filter to apply, null means copy all directories and files + * should be the same as the original + * + * @throws NullPointerException if source or destination is {@code null} + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since 1.4 + */ + public static void copyDirectory(final File srcDir, final File destDir, + final FileFilter filter) throws IOException { + copyDirectory(srcDir, destDir, filter, true); + } + + /** + * Copies a filtered directory to a new location. + *

+ * This method copies the contents of the specified source directory + * to within the specified destination directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: Setting preserveFileDate to + * {@code true} tries to preserve the files' last modified + * date/times using {@link File#setLastModified(long)}, however it is + * not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + *

+ *

Example: Copy directories only

+ *
+     *  // only copy the directory structure
+     *  FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY, false);
+     *  
+ * + *

Example: Copy directories and txt files

+ *
+     *  // Create a filter for ".txt" files
+     *  IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
+     *  IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
+     *
+     *  // Create a filter for either directories or ".txt" files
+     *  FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
+     *
+     *  // Copy using the filter
+     *  FileUtils.copyDirectory(srcDir, destDir, filter, false);
+     *  
+ * + * @param srcDir an existing directory to copy, must not be {@code null} + * @param destDir the new directory, must not be {@code null} + * @param filter the filter to apply, null means copy all directories and files + * @param preserveFileDate true if the file date of the copy + * should be the same as the original + * + * @throws NullPointerException if source or destination is {@code null} + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since 1.4 + */ + public static void copyDirectory(final File srcDir, final File destDir, + final FileFilter filter, final boolean preserveFileDate) throws IOException { + checkFileRequirements(srcDir, destDir); + if (!srcDir.isDirectory()) { + throw new IOException("Source '" + srcDir + "' exists but is not a directory"); + } + if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())) { + throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same"); + } + + // Cater for destination being directory within the source directory (see IO-141) + List exclusionList = null; + if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath())) { + final File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter); + if (srcFiles != null && srcFiles.length > 0) { + exclusionList = new ArrayList<>(srcFiles.length); + for (final File srcFile : srcFiles) { + final File copiedFile = new File(destDir, srcFile.getName()); + exclusionList.add(copiedFile.getCanonicalPath()); + } + } + } + doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList); + } + + /** + * checks requirements for file copy + * @param src the source file + * @param dest the destination + * @throws FileNotFoundException if the destination does not exist + */ + private static void checkFileRequirements(final File src, final File dest) throws FileNotFoundException { + if (src == null) { + throw new NullPointerException("Source must not be null"); + } + if (dest == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!src.exists()) { + throw new FileNotFoundException("Source '" + src + "' does not exist"); + } + } + + /** + * Internal copy directory method. + * + * @param srcDir the validated source directory, must not be {@code null} + * @param destDir the validated destination directory, must not be {@code null} + * @param filter the filter to apply, null means copy all directories and files + * @param preserveFileDate whether to preserve the file date + * @param exclusionList List of files and directories to exclude from the copy, may be null + * @throws IOException if an error occurs + * @since 1.1 + */ + private static void doCopyDirectory(final File srcDir, final File destDir, final FileFilter filter, + final boolean preserveFileDate, final List exclusionList) + throws IOException { + // recurse + final File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter); + if (srcFiles == null) { // null if abstract pathname does not denote a directory, or if an I/O error occurs + throw new IOException("Failed to list contents of " + srcDir); + } + if (destDir.exists()) { + if (destDir.isDirectory() == false) { + throw new IOException("Destination '" + destDir + "' exists but is not a directory"); + } + } else { + if (!destDir.mkdirs() && !destDir.isDirectory()) { + throw new IOException("Destination '" + destDir + "' directory cannot be created"); + } + } + if (destDir.canWrite() == false) { + throw new IOException("Destination '" + destDir + "' cannot be written to"); + } + for (final File srcFile : srcFiles) { + final File dstFile = new File(destDir, srcFile.getName()); + if (exclusionList == null || !exclusionList.contains(srcFile.getCanonicalPath())) { + if (srcFile.isDirectory()) { + doCopyDirectory(srcFile, dstFile, filter, preserveFileDate, exclusionList); + } else { + doCopyFile(srcFile, dstFile, preserveFileDate); + } + } + } + + // Do this last, as the above has probably affected directory metadata + if (preserveFileDate) { + destDir.setLastModified(srcDir.lastModified()); + } + } + + + /** + * Copies a file or directory to within another directory preserving the file dates. + *

+ * This method copies the source file or directory, along all its contents, to a + * directory of the same name in the specified destination directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: This method tries to preserve the files' last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + * + * @param src an existing file or directory to copy, must not be {@code null} + * @param destDir the directory to place the copy in, must not be {@code null} + * + * @throws NullPointerException if source or destination is {@code null} + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyDirectoryToDirectory(File, File) + * @see #copyFileToDirectory(File, File) + * @since 2.6 + */ + public static void copyToDirectory(final File src, final File destDir) throws IOException { + if (src == null) { + throw new NullPointerException("Source must not be null"); + } + if (src.isFile()) { + copyFileToDirectory(src, destDir); + } else if (src.isDirectory()) { + copyDirectoryToDirectory(src, destDir); + } else { + throw new IOException("The source " + src + " does not exist"); + } + } + + /** + * Copies a files to a directory preserving each file's date. + *

+ * This method copies the contents of the specified source files + * to a file of the same name in the specified destination directory. + * The destination directory is created if it does not exist. + * If the destination file exists, then this method will overwrite it. + *

+ * Note: This method tries to preserve the file's last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that the operation will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcs a existing files to copy, must not be {@code null} + * @param destDir the directory to place the copy in, must not be {@code null} + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFileToDirectory(File, File) + * @since 2.6 + */ + public static void copyToDirectory(final Iterable srcs, final File destDir) throws IOException { + if (srcs == null) { + throw new NullPointerException("Sources must not be null"); + } + for (final File src : srcs) { + copyFileToDirectory(src, destDir); + } + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/GeneralUtils.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/GeneralUtils.groovy index f840a3c7..a96829a4 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/GeneralUtils.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/GeneralUtils.groovy @@ -2,9 +2,10 @@ package net.sf.jremoterun.utilities.nonjdk import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.nonjdk.classpath.tester.ClasspathTester -import org.apache.commons.io.output.TeeOutputStream +import net.sf.jremoterun.utilities.nonjdk.nativeprocess.NativeProcessResult +import java.text.SimpleDateFormat +import java.util.logging.Level import java.util.logging.Logger @CompileStatic @@ -12,17 +13,19 @@ class GeneralUtils { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - static List defaultEnv = createDefaultEnv2() + + public static long defaultLogIntervalInSeconds = 3600 + static Thread startLogTimer() { - startLogTimer(3600_000) + startLogTimer(defaultLogIntervalInSeconds * 1000) } static Thread startLogTimer(long interval) { Runnable r = { while (true) { Thread.sleep(interval) - println "Log time : ${new Date().format("yyyy-MM-dd HH:mm:ss")}" + println "Log time : ${new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())}" } } @@ -32,81 +35,93 @@ class GeneralUtils { return thread } - static List createEnvFromMap(Map getenv) { - return getenv.entrySet().collect { "${it.key}=${it.value}".toString() }; + static void checkDiskFreeSpace(File file, long minFreeSpaceInMb) throws IOException { + if (!file.exists()) { + throw new FileNotFoundException(file.getAbsolutePath()); + } + long freeSpace = file.getFreeSpace() / 1_000_000 as long; + if (freeSpace < minFreeSpaceInMb) { + throw new IOException("low free space " + freeSpace + " mb in " + file.getAbsolutePath()); + } + } + + static Properties readPropsFromFile(File file) { + assert file.exists() + Properties props = new Properties() + BufferedInputStream inputStream = file.newInputStream() + try { + props.load(inputStream) + } finally { + try { + inputStream.close() + } catch (Exception e) { + log.log(Level.INFO, "failed close ${file}", e); + } + } } + /* + + @Deprecated + static List defaultEnv = NativeProcessResult.createDefaultEnv2() + + @Deprecated static List createDefaultEnv2() { - return createEnvFromMap(createDefaultEnv()) + return NativeProcessResult.createDefaultEnv2() } + @Deprecated static Map createDefaultEnv() { - Map getenv = new Hashtable<>(System.getenv()); - getenv.remove('GROOVY_OPTS') - getenv.remove('groovypath') - getenv = getenv.findAll { it.key != null && it.key.length() > 0 && it.value != null && it.value.length() > 0 } - return getenv; + return NativeProcessResult.createDefaultEnv(); } + @Deprecated static Process runNativeProcess2(String cmd, File runDir) { Process process = cmd.execute(defaultEnv, runDir); process.consumeProcessOutput(System.out, System.err); return process; } + @Deprecated static Process runNativeProcessWithTimeout(String cmd, File runDir, long timeoutInSec, Runnable doIfTimeout) { Process process = cmd.execute(defaultEnv, runDir); - LastByteArrayOutputStream outLast = new LastByteArrayOutputStream() - LastByteArrayOutputStream errLast = new LastByteArrayOutputStream() - OutputStream outTee = new TeeOutputStream(outLast, System.out) - OutputStream errTee = new TeeOutputStream(errLast, System.err) - process.consumeProcessOutput(outTee, errTee) - int exitCode = -1; - Runnable r = { - exitCode = process.waitFor() - } - Thread thread = new Thread(r) - thread.start() - thread.join(timeoutInSec * 1000) - if (thread.isAlive()) { - log.info("Process still alive : ${cmd}") - doIfTimeout.run(); - } else { - if (exitCode != 0) { - String errOut = errLast.toString() - String outOut = outLast.toString() - throw new BadExitCodeException("Bad exit ${exitCode} : ${errOut},\n${outOut}") + NativeProcessResult processResult = new NativeProcessResult(process) { + @Override + void onTimeout() { + log.info("process running long : ${cmd}") + doIfTimeout.run() } } + processResult.out2.addNonClosableStream(System.out) + processResult.err2.addNonClosableStream(System.err) + processResult.timeoutInSec = timeoutInSec + processResult.waitWithPeriodicCheck() return process } + @Deprecated static Process runNativeProcess(String cmd) { return runNativeProcess(cmd, null, true); } + @Deprecated static void waitFinish(Process process, OutputStream outStream, OutputStream errStream, boolean exceptionOnError) { - LastByteArrayOutputStream outLast = new LastByteArrayOutputStream() - LastByteArrayOutputStream errLast = new LastByteArrayOutputStream() - OutputStream outTee = outStream == null ? outLast : new TeeOutputStream(outLast, outStream) - OutputStream errTee = errStream == null ? errLast : new TeeOutputStream(errLast, errStream) - Thread threadOut = process.consumeProcessOutputStream(outTee) - Thread threadErr = process.consumeProcessErrorStream(errTee) - int exitCode = process.waitFor() - log.fine "exit code : ${exitCode}" - threadOut.join() - threadErr.join() - if (exitCode != 0) { - String errOut = errLast.toString() - String outOut = outLast.toString() - if (exceptionOnError) { - throw new BadExitCodeException("Bad exit ${exitCode} : ${errOut},\n${outOut}") - }else{ - log.info "bad exit code ${exitCode} : ${errOut},\n${outOut}" + NativeProcessResult nativeProcessResult = new NativeProcessResult(process) { + @Override + void onTimeout() { + log.info "process running too long" } } + if (outStream != null) { + nativeProcessResult.out2.addNonClosableStream(outStream) + } + if (errStream != null) { + nativeProcessResult.err2.addNonClosableStream(errStream) + } + nativeProcessResult.exceptionOnError = exceptionOnError } + @Deprecated static Process runNativeProcess(String cmd, File runDir, boolean exceptionOnError) { if (runDir != null) { assert runDir.exists() @@ -116,14 +131,28 @@ class GeneralUtils { return process; } + @Deprecated + static Process runNativeProcessRedirectOutputToFile(String cmd, File runDir, boolean exceptionOnError, File outputFile, int rotationDepth) { + if (runDir != null) { + assert runDir.exists() + } + FileRotate.rotateFile(outputFile, rotationDepth) + BufferedOutputStream outputStream2 = outputFile.newOutputStream() + Process process = cmd.execute(defaultEnv, runDir); + try { + waitFinish(process, outputStream2, outputStream2, exceptionOnError) + } finally { + try { + outputStream2.flush() + outputStream2.close() + } catch (Throwable e) { + log.info("failed close file : ${outputFile}", e) + } - public static void checkDiskFreeSpace(File file, long minFreeSpaceInMb) throws IOException { - long freeSpace = file.getFreeSpace() / 1_000_000 as long; - if (freeSpace < minFreeSpaceInMb) { - throw new IOException("low free space " + freeSpace + " mb in " + file.getAbsolutePath()); } + return process; } - +*/ } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/LastByteArrayOutputStream.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/LastByteArrayOutputStream.groovy index 34b95b88..d87b041c 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/LastByteArrayOutputStream.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/LastByteArrayOutputStream.groovy @@ -17,15 +17,22 @@ class LastByteArrayOutputStream extends ByteArrayOutputStream { */ public static int bufferSizeDefault = 16_000; - int msgSize = msgSizeDefault + int msgSize ; - byte[] buf1 = new byte[bufferSizeDefault] - byte[] buf2 = new byte[bufferSizeDefault] + byte[] buf1; + byte[] buf2; boolean usesFirst = true LastByteArrayOutputStream() { + this(msgSizeDefault,bufferSizeDefault) + } + + LastByteArrayOutputStream(int msgSize,int bufferSize) { super(0) + this.msgSize=msgSize; + buf1 = new byte[bufferSize] + buf2 = new byte[bufferSize] buf = buf1 } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/NpeFixAgent.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/NpeFixAgent.groovy new file mode 100644 index 00000000..cf0bf6ab --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/NpeFixAgent.groovy @@ -0,0 +1,42 @@ +package net.sf.jremoterun.utilities.nonjdk + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs +import org.apache.commons.lang3.SystemUtils; + +import java.util.logging.Logger; + +@CompileStatic +class NpeFixAgent { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static File linkToRef; + public static String javaArgStr; + + static File getRefToRichNpeLib(){ + if(linkToRef!=null){ + return linkToRef + } + String suffix ; + + if(SystemUtils.IS_OS_WINDOWS){ + suffix = 'dll' + }else{ + suffix = 'so' + } + FileChildLazyRef richNpeDir = GitSomeRefs.ifFramework.childL('richNpe/richNPE64.'+suffix) + linkToRef= richNpeDir.resolveToFile(); + return linkToRef + } + + static String buildPathString(){ + if(javaArgStr!=null){ + return javaArgStr + } + String path = getRefToRichNpeLib().getAbsolutePath().replace('\\','/') + javaArgStr = "-agentpath:${path}" + return javaArgStr + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/RedirectOutStream.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/RedirectOutStream.groovy index 8cca9832..47e46c33 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/RedirectOutStream.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/RedirectOutStream.groovy @@ -14,6 +14,9 @@ public class RedirectOutStream { private static final Logger log = Logger.getLogger(JrrClassUtils.getCurrentClass().getName()); public static void setOutStreamWithRotation(File file,int maxCount) throws Exception { + if(file==null){ + throw new NullPointerException("argument file is null") + } if (file.exists()) { try { FileRotate.rotateFile(file, maxCount); diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/StringFindRange.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/StringFindRange.groovy index 8b015f6c..660c22e4 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/StringFindRange.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/StringFindRange.groovy @@ -5,14 +5,17 @@ import net.sf.jremoterun.utilities.JrrClassUtils import java.util.logging.Logger +/** + * By default symbol excluded, if not written 'Inclusive' + */ @CompileStatic class StringFindRange { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - String s; - int begin; - int end; + public String s; + public int begin; + public int end; StringFindRange(String s, int begin, int end) { this.s = s @@ -26,10 +29,28 @@ class StringFindRange { end = s.length() - 1 } - String subExclusive() { + + void skipFromBegining(int numSyn){ + int newEnd = end - numSyn + assert newEnd >0 + begin = numSyn; + end = newEnd + + } + + /** + * by default return the same as in : new consctuctor(s) + */ + String subStringInclusiveBoth() { + assert end + 1 <= s.length() return s.substring(begin, end + 1) } + @Override + String toString() { + return subStringInclusiveBoth() + } + String subStringExlusiveBoth() { assert begin+1<=end return s.substring(begin+1, end ) @@ -39,15 +60,10 @@ class StringFindRange { return s.substring(begin, end ) } - String subStringInclusiveEnd() { return s.substring(begin+1, end+1 ) } - String subStringInclusiveBoth() { - assert end + 1 <= s.length() - return s.substring(begin, end + 1) - } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/ThreeResult.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/ThreeResult.groovy index 52a3085f..5f91a11c 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/ThreeResult.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/ThreeResult.groovy @@ -20,4 +20,10 @@ public class ThreeResult extends TwoResult{ V getThird() { return third } + + + @Override + String toString() { + return "${first} , ${second} , ${third}" + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/TwoResult.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/TwoResult.groovy index 94b7703f..55d0cb6d 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/TwoResult.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/TwoResult.groovy @@ -25,4 +25,9 @@ class TwoResult implements Serializable{ E getSecond() { return second } + + @Override + String toString() { + return "${first} , ${second}" + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmConsoleDecompiler.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmConsoleDecompiler.groovy new file mode 100644 index 00000000..85298371 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmConsoleDecompiler.groovy @@ -0,0 +1,60 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2 + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.groovystarter.ClassNameSynonym +import org.objectweb.asm.ClassReader +import org.objectweb.asm.Opcodes +import org.objectweb.asm.util.ASMifier +import org.objectweb.asm.util.Printer +import org.objectweb.asm.util.Textifier +import org.objectweb.asm.util.TraceClassVisitor; + +import java.util.logging.Logger; + +@CompileStatic +class AsmConsoleDecompiler implements ClassNameSynonym{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static int asmCode = Opcodes.ASM7 + public static int options = 0 + + + /** + * options - 0 for all, + * @see org.objectweb.asm.ClassReader#SKIP_DEBUG + */ + void printAll(String className, boolean asAsm) { + ClassReader cr = new ClassReader(className); + String code2 = printAll2(cr, asAsm) + log.info "code : \n ${code2}" + } + + String printAll2(ClassReader cr, boolean asAsm) { + Printer printer = asAsm ? new Textifier() : new ASMifier() + StringWriter stringWriter = new StringWriter() + TraceClassVisitor visitor = new TraceClassVisitor(null, printer, new PrintWriter(stringWriter, true)) + cr.accept(visitor, options); +// String join = printer.text.join('') + String code2 = stringWriter.toString() + return code2 + } + + void printMethod(String className, String methodName, boolean asAsm) { + ClassReader cr = new ClassReader(className); + String join = printMethod2(cr, methodName, asAsm) + log.info "code : \n ${join}" + } + + String printMethod2(ClassReader cr, String methodName, boolean asAsm) { + Printer printer = asAsm ? new Textifier() : new ASMifier() + AsmConsoleDecompilerVisitor visitor = new AsmConsoleDecompilerVisitor(asmCode, null, methodName, printer) + cr.accept(visitor, options); + if (!visitor.found) { + throw new NoSuchMethodException("${cr.className} ${methodName}") + } + String join = printer.text.join('') + return join + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmConsoleDecompilerVisitor.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmConsoleDecompilerVisitor.groovy new file mode 100644 index 00000000..0386c40c --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmConsoleDecompilerVisitor.groovy @@ -0,0 +1,38 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2 + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.util.Printer +import org.objectweb.asm.util.TraceMethodVisitor; + +import java.util.logging.Logger; + +@CompileStatic +class AsmConsoleDecompilerVisitor extends ClassVisitor { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + String decompileMethod + Printer textifier; + + public boolean found = false + + AsmConsoleDecompilerVisitor(int api, ClassVisitor classVisitor, String decompileMethod, Printer textifier) { + super(api, classVisitor) + this.decompileMethod = decompileMethod + this.textifier = textifier + } + + @Override + MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + MethodVisitor methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions) + if (name == decompileMethod) { + found = true +// String sig = signature == null ? "" : signature + textifier.text.add("Begin ${name} ${descriptor} \n".toString()) + return new TraceMethodVisitor(methodVisitor, textifier) + } + return methodVisitor + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmUtils.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmUtils.groovy new file mode 100644 index 00000000..00be2e5c --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/AsmUtils.groovy @@ -0,0 +1,132 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2 + +import groovy.transform.CompileStatic +import net.sf.jremoterun.SimpleJvmTiAgent +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.nonjdk.asmow2.verifier.AsmByteCodeVerifier +import org.apache.commons.io.IOUtils +import org.objectweb.asm.ClassReader +import org.objectweb.asm.ClassWriter +import org.objectweb.asm.commons.ClassRemapper +import org.objectweb.asm.commons.SimpleRemapper +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.MethodNode +import org.objectweb.asm.tree.analysis.Analyzer +import org.objectweb.asm.tree.analysis.SimpleVerifier + +import java.lang.instrument.ClassDefinition +import java.util.logging.Logger + +@CompileStatic +class AsmUtils { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + AsmByteCodeVerifier asmByteCodeVerifier = new AsmByteCodeVerifier(getClass().getClassLoader()) + + @Deprecated + ClassNode verifyByteCode(byte[] byteCode) { + return asmByteCodeVerifier.verifyByteCode(byteCode) + } + + + static String convertClassPath(ClRef fromClass) { + return fromClass.getClassName().replace('.', '/') + } + + static String convertClassPath(Class fromClass) { + return fromClass.getName().replace('.', '/') + } + + SimpleRemapperUsed createRemapperForClass(ClRef fromClass, ClRef toClass) { + Map remapperMap = [:] + remapperMap.put(convertClassPath(fromClass), convertClassPath(toClass)); + SimpleRemapperUsed remapper = new SimpleRemapperUsed(remapperMap) + return remapper; + } + + static byte[] readClass(Class clazz) { + String path = convertClassPath(clazz) + '.class' + InputStream stream = clazz.getClassLoader().getResourceAsStream(path) + byte[] array = IOUtils.toByteArray(stream) + stream.close() + return array + } + + boolean remapConstOnly = false + + void remapClassConstructor(Class inClass, Class childClass) { + remapConstOnly = true + remapClass(inClass, childClass.getSuperclass(), childClass) + } + + void remapClass(Class inClass, Class fromClass, Class toClass) { + byte[] clazz = readClass(inClass) + byte[] res = remapClassNoRedefine(new ClassReader(clazz), fromClass, toClass) + redefineClass(res, inClass) + } + + ClassRemapper createClassRemapper(ClassWriter cw, SimpleRemapper remapper) { + if (remapConstOnly) { + return new ClassRemapperConst(cw, remapper); + } + return new ClassRemapper(cw, remapper) + } + + byte[] makeMethodEmpty(ClassReader cr, String methodName, int argsCount) { + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); + EmptyMethodClassVisitor classVisitor = new EmptyMethodClassVisitor(methodName, argsCount, cw); + cr.accept(classVisitor, 0); + byte[] b2 = cw.toByteArray(); + if (!classVisitor.found) { + throw new Exception("Method not found : ${methodName} with args count = ${argsCount} in class ${cr.className}") + } + asmByteCodeVerifier.verifyByteCode(b2) + return b2 + } + + byte[] remapClassNoRedefine(ClassReader cr, Class fromClass, Class toClass) { + return remapClassNoRedefine(cr,new ClRef(fromClass),new ClRef(toClass)) + } + + byte[] remapClassNoRedefine(ClassReader cr, ClRef fromClass, ClRef toClass) { + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); + SimpleRemapperUsed remapper = createRemapperForClass(fromClass, toClass) + ClassRemapper classRemapper = createClassRemapper(cw, remapper) + cr.accept(classRemapper, 0); + byte[] b2 = cw.toByteArray(); + if (!remapper.used) { + throw new Exception("Remapper was not used : ${remapper.mapping2}") + } + if (remapConstOnly) { + asmByteCodeVerifier.verifyByteCode(b2) + } + return b2 + } + + + + + void redefineClassWithVerify(final byte[] bs, Class class1) { + String classPath = convertClassPath(class1) + ClassNode classNode = asmByteCodeVerifier.verifyByteCode(bs) +// log.info "validation passed" + if (classNode.name != classPath) { + throw new IllegalArgumentException("classes diff : ${classPath} , ${classNode.name}") + } + redefineClass(bs, class1) + } + + static void redefineClass(final byte[] bs, Class class1) + throws Exception { + final ClassDefinition classDefinition = new ClassDefinition(class1, bs); + final ClassDefinition[] classDefinitions = [classDefinition]; + if (SimpleJvmTiAgent.instrumentation == null) { + throw new NullPointerException("SimpleJvmTiAgent.instrumentation is null"); + } + SimpleJvmTiAgent.instrumentation.redefineClasses(classDefinitions); + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/ClassRemapperConst.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/ClassRemapperConst.groovy new file mode 100644 index 00000000..aa19044c --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/ClassRemapperConst.groovy @@ -0,0 +1,38 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2 + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.FieldVisitor +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.commons.ClassRemapper +import org.objectweb.asm.commons.FieldRemapper +import org.objectweb.asm.commons.Remapper +import org.objectweb.asm.commons.SimpleRemapper; + +import java.util.logging.Logger; + +@CompileStatic +class ClassRemapperConst extends ClassRemapper{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + Remapper remapper2 + + MethodRemapperConst methodRemapperConst + + ClassRemapperConst(ClassVisitor classVisitor, Remapper remapper2) { + super(classVisitor, new SimpleRemapper([:])) + this.remapper2 = remapper2 + } + + @Override + protected FieldVisitor createFieldRemapper(FieldVisitor fieldVisitor) { + return new FieldRemapper(fieldVisitor, remapper); + } + + @Override + protected MethodVisitor createMethodRemapper(MethodVisitor methodVisitor) { + methodRemapperConst = new MethodRemapperConst(methodVisitor, remapper2) + return methodRemapperConst + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyClassVisitor.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyClassVisitor.groovy new file mode 100644 index 00000000..20d208b5 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyClassVisitor.groovy @@ -0,0 +1,25 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2 + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.Opcodes; + +import java.util.logging.Logger; + +@CompileStatic +class EmptyClassVisitor extends ClassVisitor{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + EmptyClassVisitor() { + super(AsmConsoleDecompiler.asmCode) + } + + EmptyClassVisitor(int api) { + super(api) + } + + EmptyClassVisitor(int api, ClassVisitor classVisitor) { + super(api, classVisitor) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyMethodClassVisitor.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyMethodClassVisitor.groovy new file mode 100644 index 00000000..60f7eec3 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyMethodClassVisitor.groovy @@ -0,0 +1,48 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2 + +import groovy.transform.CompileStatic +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.Opcodes +import org.objectweb.asm.Type + +@CompileStatic +class EmptyMethodClassVisitor extends ClassVisitor { + + String skipMethodName; + int argCount; + boolean found = false + + EmptyMethodClassVisitor(String skipMethodName, int argCount,final ClassVisitor classVisitor) { + super(AsmConsoleDecompiler.asmCode,classVisitor) + this.skipMethodName = skipMethodName + this.argCount = argCount + } + + @Override + MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + Type[] types = Type.getArgumentTypes(descriptor) + if (needVisitMethod(access, name, descriptor, signature, exceptions, types)) { + return super.visitMethod(access, name, descriptor, signature, exceptions) + } + MethodVisitor visitMethodP = super.visitMethod(access, name, descriptor, signature, exceptions) + visitMethodP.visitCode() + visitMethodP.visitInsn(Opcodes.RETURN); + visitMethodP.visitMaxs(0,0) + visitMethodP.visitEnd() +// return new EmptyMethodVisitor(api,visitMethodP) + return null; + } + + + boolean needVisitMethod(int access, String name, String descriptor, String signature, String[] exceptions, Type[] types) { + if (name == skipMethodName && types.length == argCount) { + if (found) { + throw new Exception("Found 2 or more methods : ${name} with args count : ${types.length}") + } + found = true + return false + } + return true + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyMethodVisitor.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyMethodVisitor.groovy new file mode 100644 index 00000000..8b199c62 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/EmptyMethodVisitor.groovy @@ -0,0 +1,29 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2 + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.objectweb.asm.MethodVisitor; + +import java.util.logging.Logger; + +@CompileStatic +class EmptyMethodVisitor extends MethodVisitor{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + EmptyMethodVisitor(int api) { + super(api) + } + + EmptyMethodVisitor(int api, MethodVisitor methodVisitor) { + super(api, methodVisitor) + } + + + + @Override + void visitCode() { + // Thread.dumpStack() + mv = null +// super.visitCode() + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/MethodRemapperConst.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/MethodRemapperConst.groovy new file mode 100644 index 00000000..c9c645c6 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/MethodRemapperConst.groovy @@ -0,0 +1,56 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2 + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.commons.MethodRemapper +import org.objectweb.asm.commons.Remapper +import org.objectweb.asm.commons.SimpleRemapper; + +import java.util.logging.Logger; + +@CompileStatic +class MethodRemapperConst extends MethodRemapper { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + Remapper remapper2 + +// public boolean used = false + + MethodRemapperConst(MethodVisitor methodVisitor, Remapper remapper2) { + super(methodVisitor, new SimpleRemapper([:])) + this.remapper2 = remapper2 + } + + + @Override + void visitTypeInsn(int opcode, String type) { + String res = remapper2.mapType(type) +// if (type != res) { +// used = true +// } + super.visitTypeInsn(opcode, res); + } + + + @Override + void visitMethodInsn(final int opcodeAndSource, final String owner, final String name, final String descriptor, final boolean isInterface) { + visitMethodInsnImpl(opcodeAndSource, owner, name, descriptor, isInterface); + } + + void visitMethodInsnSuper(final int opcodeAndSource, final String owner, final String name, final String descriptor, final boolean isInterface) { + super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface); + } + + void visitMethodInsnImpl(final int opcodeAndSource, String owner, final String name, final String descriptor, final boolean isInterface) { + boolean b = name == '' + if (b) { + owner = remapper2.mapType(owner) +// if (owner != res) { +// used = true +// } +// owner = res; + } + visitMethodInsnSuper(opcodeAndSource, owner, name, descriptor, isInterface); + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/SimpleRemapperUsed.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/SimpleRemapperUsed.groovy new file mode 100644 index 00000000..4381ae61 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/SimpleRemapperUsed.groovy @@ -0,0 +1,27 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2 + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.objectweb.asm.commons.SimpleRemapper; + +import java.util.logging.Logger; + +@CompileStatic +class SimpleRemapperUsed extends SimpleRemapper{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + Map mapping2 + boolean used = false + + SimpleRemapperUsed(Map mapping) { + super(mapping) + mapping2 = mapping + } + + @Override + String map(String key) { + if(mapping2.containsKey(key)){ + used = true + } + return super.map(key) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/AccessClassVisitor.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/AccessClassVisitor.groovy new file mode 100644 index 00000000..777ce6c0 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/AccessClassVisitor.groovy @@ -0,0 +1,192 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.accessmodif + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.asmow2.AsmConsoleDecompiler +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes + +import java.util.logging.Logger; + +@CompileStatic +class AccessClassVisitor extends ClassVisitor { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + boolean needMakeAllPublic + boolean needMakeAllPublicTmp + AccessModifController accessModifController + ClassReader classReader +// String innerClass + + AccessClassVisitor(ClassVisitor classVisitor, AccessModifController accessModifController, ClassReader classReader) { + super(AsmConsoleDecompiler.asmCode, classVisitor); + this.accessModifController = accessModifController + this.classReader = classReader + needMakeAllPublic = accessModifController.needMakeAllPublic(classReader) + } + + + @Override + void visit(final int version, int access, final String name, final String signature, final String superName, final String[] interfaces) { + boolean isInnerClass = name.contains('$'); + if (isInnerClass) { + boolean b = accessModifController.decideAccessForInnderClass(classReader, name, access) + if (b) { + needMakeAllPublicTmp = true +// access = removeFinalModifierAndMakePublic(access) + } + } +// log.info "${name} needMakeAllPublicTmp = ${needMakeAllPublicTmp}, needMakeAllPublic = ${needMakeAllPublic}" + if (needMakeAllPublicTmp || needMakeAllPublic || !isInnerClass) { + access = removeFinalModifierAndMakePublic(access); + } else { + access = removeFinalModifier(access); + } + +// log.info "visit class begin ${name}" + super.visit(version, access, name, signature, superName, interfaces); +// log.info "visit class end ${name}" + } + + @Override + void visitOuterClass(String owner, String name, String descriptor) { +// log.info "visitOuterClass ${name} begin" + super.visitOuterClass(owner, name, descriptor) +// log.info "visitOuterClass ${name} end" + } + + @Override + void visitEnd() { +// log.info "visitEnd" +// innerClass = null + needMakeAllPublicTmp = false + super.visitEnd() + } + + + @Override + void visitInnerClass(String name, String outerName, String innerName, int access) { +// boolean isFinal = access & ~Opcodes.ACC_FINAL; +// if (isFinal || needMakeAllPublicTmp || needMakeAllPublic) { + access = removeFinalModifierAndMakePublic(access) +// } else { +// access = removeFinalModifier(access) +// } +// log.info("inner ${innerName} ${needMakeAllPublicTmp}") + super.visitInnerClass(name, outerName, innerName, access); + } + + +// @Override +// void visitInnerClass(String name, String outerName, String innerName, int access) { +//// visitInnerClass = true +//// innerClass = innerName +// boolean b = accessModifController.decideAccessForInnderClass(classReader, name, outerName, innerName, access) +// if (name.contains("RSyntaxTextArea")) { +// log.info "innter ${innerName} : ${b} begin" +// } +// if (b) { +// needMakeAllPublicTmp = true +// access = removeFinalModifierAndMakePublic(access) +// } +// super.visitInnerClass(name, outerName, innerName, access); +// log.info "innter ${innerName} : ${b} end" +// } + + + + @Override + MethodVisitor visitMethod(int access, final String name, final String desc, final String signature, final String[] exceptions) { + return createMethodVisitor(access, name, desc, signature, exceptions); + } + + MethodVisitor createMethodVisitor(int access, final String name, final String desc, final String signature, final String[] exceptions){ + int access1 = handleMethodAccess(access, name); + MethodVisitor methodVisitorParent = visitMethodI(access1, name, desc, signature, exceptions); + JrrMethodVisitor jrrMethodVisitor = new JrrMethodVisitor(api,methodVisitorParent,accessModifController) + return jrrMethodVisitor + } + + + @Override + FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { + access = handleFieldAccess(access, name) + return super.visitField(access, name, descriptor, signature, value) + } + + int handleFieldAccess(int access, String name) { +// log.info "handle ${}" + access = handleMemberAccess(access) + return access + } + + public static String contsructorMethodName = '' + + + int handleMethodAccess(int access, String name) { + access = handleMemberAccess(access) + boolean needPublic=name == contsructorMethodName + if(!needPublic) { + needPublic = accessModifController.needMakeMethodPublic(name, classReader) + } + if (needPublic) { + + access = makePublic(access) + } + return access + } + + int handleMemberAccess(int access) { + access = removeFinalModifier(access) + boolean b = needMakeAllPublic || needMakeAllPublicTmp || (access & Opcodes.ACC_PROTECTED) > 0 + if (b) { + access = makePublic(access) + } + return access + + } + + int makePublic(int access) { + access = access & ~Opcodes.ACC_PRIVATE; ; + access = access & ~Opcodes.ACC_PROTECTED; ; + access = access | Opcodes.ACC_PUBLIC; + return access + } + + + int removeFinalModifierAndMakePublic(int access) { + access = removeFinalModifier(access) + access = makePublic(access) + return access + } + + int removeFinalModifier(int access) { + return access & ~Opcodes.ACC_FINAL; + } + + + void visitI(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { + super.visit(version, access, name, signature, superName, interfaces); + } + + + void visitInnerClassI(String name, String outerName, String innerName, int access) { + super.visitInnerClass(name, outerName, innerName, access); + } + + + MethodVisitor visitMethodI(int access, final String name, final String desc, final String signature, final String[] exceptions) { + return super.visitMethod(access, name, desc, signature, exceptions); + } + + + FieldVisitor visitFieldI(int access, String name, String descriptor, String signature, Object value) { + return super.visitField(access, name, descriptor, signature, value) + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/AccessModifController.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/AccessModifController.groovy new file mode 100644 index 00000000..ce2c8332 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/AccessModifController.groovy @@ -0,0 +1,163 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.accessmodif + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.nonjdk.asmow2.AsmUtils +import net.sf.jremoterun.utilities.nonjdk.asmow2.verifier.AsmByteCodeVerifier +import org.objectweb.asm.ClassReader +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.ClassWriter +import org.objectweb.asm.Opcodes + +import java.util.logging.Logger +import java.util.zip.ZipEntry + +@CompileStatic +abstract class AccessModifController { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + AsmUtils asmUtils = new AsmUtils() + AsmByteCodeVerifier asmByteCodeVerifier = new AsmByteCodeVerifier(getClass().getClassLoader()) + Set makeClassPublic = new HashSet<>() + Set ignoreModifyClasses = new HashSet<>() + Set modifiedClasses = new HashSet<>() + + + void addMakeClassPublic(ClRef clRef){ + makeClassPublic.add(clRef.getClassName().replace('.','/')) + } + + + void addIgnoreModifyClasses(ClRef clRef){ + ignoreModifyClasses.add(clRef.getClassName().replace('.','/')) + } + + boolean needEntry(ZipEntry zipEntry) { + return true + } + + + boolean needModifyClass(ClassReader className) { + String find1 = ignoreModifyClasses.find { className.getClassName().startsWith(it) } + if(find1==null){ + return true + } + return false + } + + byte[] removeFinalModifier(String classNameWIthShash, byte[] bs) { + final ClassReader reader = new ClassReader(bs); + if (needModifyClass(reader)) { + modifiedClasses.add(reader.getClassName().replace('/','.')) + return removeFinalModifier2(reader, bs) + } + return bs + } + + + void onFinish() { + + } + + byte[] removeFinalModifier2(ClassReader reader, byte[] bs) { + boolean isInterface = (reader.getAccess() & Opcodes.ACC_INTERFACE) > 0 + if (isInterface) { + return bs; + } + final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); + reader.accept(createClassVisitor(reader, writer), 0); + byte[] array = writer.toByteArray(); + if (needVerifyClass(reader)) { + asmByteCodeVerifier.verifyByteCode(array) + } + return array + } + + boolean needVerifyClass(ClassReader reader) { + return false + } + + String convertClassNameToShash(String className) { + return className.replace('.', '/') + } + + String convertClassNameToDot(String className) { + return className.replace('/', '.') + } + + ClassVisitor createClassVisitor(ClassReader reader, ClassWriter writer) { + return new AccessClassVisitor(writer, this, reader) + } + + boolean needMakeAllPublic(ClassReader className) { + int access = className.getAccess() + if (className.className.contains('$')) { + boolean isFinal = (access & Opcodes.ACC_FINAL) > 0 + if (isFinal) { + return true + } +// boolean isStatic = (access & Opcodes.ACC_STATIC) > 0 +// if (!isStatic) { +// return true +// } + return false + } + boolean needMakeAllPublic = (access & Opcodes.ACC_FINAL) > 0 + return needMakeAllPublic + } + + + boolean decideAccessForInnderClass(ClassReader classReader, String name, int access) { + String classFound = makeClassPublic.find {classReader.getClassName().startsWith(it)} + if(classFound==null){ + return false + } + boolean isFinal = (access & Opcodes.ACC_FINAL) > 0 + if (isFinal) { + return true + } +// boolean isStatic = (access & Opcodes.ACC_STATIC) > 0 +// if (!isStatic) { +// return true +// } + return false + } + + int modifyOpsCodeIfNeeded(int opcode, String owner, String methodName, String descriptor, boolean isInterface) { + if (opcode == Opcodes.INVOKESPECIAL) { + boolean need = isModifyOpsFromInvokeSpecialToVirtual(opcode,owner,methodName,descriptor,isInterface) + if(need) { + return Opcodes.INVOKEVIRTUAL + } + } + return opcode + } + + boolean isModifyOpsFromInvokeSpecialToVirtual(int opcode, String owner, String methodName, String descriptor, boolean isInterface) { + boolean needpublic = needMakeMethodPublic(methodName, owner) + return needpublic; + } + + /** + * @param className with separator: / + */ + boolean isNeedMakeClassPublic(String className){ + className = className.replace('.','/') + String classFound = makeClassPublic.find {className.startsWith(it)} + if(classFound==null){ + return false + } + return true + + } + + boolean needMakeMethodPublic(String methodName, String className) { + isNeedMakeClassPublic(className) + } + + boolean needMakeMethodPublic(String methodName, ClassReader classReader) { + return needMakeMethodPublic(methodName, classReader.getClassName()) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/DirAccessModifController.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/DirAccessModifController.groovy new file mode 100644 index 00000000..a31632fd --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/DirAccessModifController.groovy @@ -0,0 +1,41 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.accessmodif + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.util.logging.Logger + +@CompileStatic +class DirAccessModifController extends AccessModifController { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + void handleDirSelf(File inJarFile) { + handleDir(inJarFile,inJarFile) + } + + void handleDir(File inFileDir, File outputFileDir) { + handleDirImpl(inFileDir,outputFileDir) + onFinish() + } + + void handleDirImpl(File inFileDir, File outputFileDir) { + assert inFileDir.exists() + inFileDir.listFiles().toList().each { + File child = outputFileDir.child(it.name) + if (it.isDirectory()) { + child.mkdir() + assert child.exists() + handleDirImpl(it, child) + } else if (it.isFile()) { + handleFile(it, child) + }else{ + throw new Exception("Stange file : ${it}") + } + } + } + + void handleFile(File inFile, File outputFile) { + outputFile.bytes = removeFinalModifier(inFile.absolutePath, inFile.bytes) + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/JarAccessModifController.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/JarAccessModifController.groovy new file mode 100644 index 00000000..965f774f --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/JarAccessModifController.groovy @@ -0,0 +1,56 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.accessmodif + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import org.zeroturnaround.zip.ZipEntryCallback +import org.zeroturnaround.zip.ZipUtil + +import java.util.logging.Logger +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream + +@CompileStatic +class JarAccessModifController extends AccessModifController { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ZipOutputStream zipOutputStream + + + HashSet zipEntries = new HashSet<>() + HashSet duplicatedEntries = new HashSet<>() + HashSet skippedEntries = new HashSet<>() + + void handleJarSelf(File inJarFile) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream() + handleJarImpl(inJarFile, outputStream) + inJarFile.bytes = outputStream.toByteArray() + } + + void handleJar(File inJarFile, File outJar) { + BufferedOutputStream outputStream = outJar.newOutputStream() + handleJarImpl(inJarFile, outputStream) + } + + void handleJarImpl(File inJarFile, OutputStream outputStream) { +// BufferedOutputStream outputStream = outJarFile.newOutputStream(); + zipOutputStream = new ZipOutputStream(outputStream) + ZipEntryCallback zipEntryCallback = createZipEntryCallback() + ZipUtil.iterate(inJarFile, zipEntryCallback) + zipOutputStream.flush() + zipOutputStream.close() + onFinish() + } + + + ZipEntryCallback createZipEntryCallback(){ + return new ZipEntryCallbackAm(this) + } + + void onDuplicate(ZipEntry zipEntry) { + + } + + String saveAsName(ZipEntry zipEntry) { + return zipEntry.getName() + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/JrrMethodVisitor.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/JrrMethodVisitor.groovy new file mode 100644 index 00000000..168f2b22 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/JrrMethodVisitor.groovy @@ -0,0 +1,30 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.accessmodif + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.objectweb.asm.MethodVisitor; + +import java.util.logging.Logger; + +@CompileStatic +class JrrMethodVisitor extends MethodVisitor{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + AccessModifController accessModifController + + JrrMethodVisitor(int api, MethodVisitor methodVisitor,AccessModifController accessModifController) { + super(api, methodVisitor) + this.accessModifController = accessModifController + } + + + int modifyOpsCodeIfNeeded(int opcode, String owner, String name, String descriptor, boolean isInterface){ + return accessModifController.modifyOpsCodeIfNeeded(opcode, owner, name, descriptor, isInterface) + } + + @Override + void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { + opcode = modifyOpsCodeIfNeeded(opcode, owner, name, descriptor, isInterface) + super.visitMethodInsn(opcode, owner, name, descriptor, isInterface) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/ZipEntryCallbackAm.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/ZipEntryCallbackAm.groovy new file mode 100644 index 00000000..fe9c4601 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/accessmodif/ZipEntryCallbackAm.groovy @@ -0,0 +1,46 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.accessmodif + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.commons.io.IOUtils +import org.zeroturnaround.zip.ZipEntryCallback; + +import java.util.logging.Logger +import java.util.zip.ZipEntry + +@CompileStatic +class ZipEntryCallbackAm implements ZipEntryCallback { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + JarAccessModifController accessModifController + + ZipEntryCallbackAm(JarAccessModifController accessModifController) { + this.accessModifController = accessModifController + } + + @Override + void process(InputStream inputStream, ZipEntry zipEntry) throws IOException { + if (accessModifController.needEntry(zipEntry)) { + String name = zipEntry.getName() + if (accessModifController.zipEntries.contains(name)) { + accessModifController.onDuplicate(zipEntry) + accessModifController.duplicatedEntries.add(name) + }else { + byte[] array = IOUtils.toByteArray(inputStream) + if (name.endsWith(".class")) { + array = accessModifController.removeFinalModifier(name, array) + } + String saveAsName = accessModifController.saveAsName(zipEntry) + ZipEntry entryNew = new ZipEntry(saveAsName); + accessModifController.zipOutputStream.putNextEntry(entryNew); + accessModifController.zipOutputStream.write(array, 0, array.length) + accessModifController.zipOutputStream.closeEntry() + accessModifController.zipEntries.add(zipEntry.getName()) + } + } else { + accessModifController.skippedEntries.add(zipEntry.getName()) + } + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/usedclasses/UsedClasses.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/usedclasses/UsedClasses.groovy new file mode 100644 index 00000000..c93d05dd --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/usedclasses/UsedClasses.groovy @@ -0,0 +1,107 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.usedclasses + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.asmow2.EmptyClassVisitor +import org.objectweb.asm.ClassReader +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.Type +import org.objectweb.asm.commons.ClassRemapper +import org.objectweb.asm.commons.Remapper + +import java.util.logging.Logger; + +@CompileStatic +class UsedClasses extends Remapper{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public HashSet usedTypes = new HashSet<>() + public HashSet usedTypes2 = new HashSet<>() + + @Override + String mapType(String internalName) { + usedTypes.add(internalName) + return super.mapType(internalName) + } + + @Override + public String mapDesc(final String descriptor) { + return mapTypeJrr(Type.getType(descriptor)).getDescriptor(); + } + + @Override + public String mapMethodDesc(final String methodDescriptor) { + if ("()V".equals(methodDescriptor)) { + return methodDescriptor; + } + + StringBuilder stringBuilder = new StringBuilder("("); + for (Type argumentType : Type.getArgumentTypes(methodDescriptor)) { + stringBuilder.append(mapTypeJrr(argumentType).getDescriptor()); + } + Type returnType = Type.getReturnType(methodDescriptor); + if (returnType == Type.VOID_TYPE) { + stringBuilder.append(")V"); + } else { + stringBuilder.append(')').append(mapTypeJrr(returnType).getDescriptor()); + } + return stringBuilder.toString(); + } + + @Override + public Object mapValue(final Object value) { + if (value instanceof Type) { + return mapTypeJrr((Type) value); + } + return super.mapValue(value) + } + + /** + * {@link Remapper#mapType(org.objectweb.asm.Type)} + */ + protected Type mapTypeJrr(final Type type) { + usedTypes2.add(type) + switch (type.getSort()) { + case Type.ARRAY: + StringBuilder remappedDescriptor = new StringBuilder(); + for (int i = 0; i < type.getDimensions(); ++i) { + remappedDescriptor.append('['); + } + remappedDescriptor.append(mapTypeJrr(type.getElementType()).getDescriptor()); + return Type.getType(remappedDescriptor.toString()); + case Type.OBJECT: + usedTypes.add(type.getInternalName()) + String remappedInternalName = map(type.getInternalName()); + return remappedInternalName != null ? Type.getObjectType(remappedInternalName) : type; + case Type.METHOD: + return Type.getMethodType(mapMethodDesc(type.getDescriptor())); + default: + return type; + } + } + + static UsedClasses remapClassNoRedefine(byte[] bytes) { + UsedClasses usedClasses = new UsedClasses() + ClassReader classReader = new ClassReader(bytes); + remapClassNoRedefine1(classReader,usedClasses); + usedClasses.usedTypes.remove(classReader.getClassName()) + return usedClasses; + } + + + static void remapClassNoRedefine1(ClassReader classReader, UsedClasses usedClasses ) { + ClassVisitor cw = new EmptyClassVisitor(); + ClassRemapper classRemapper = new ClassRemapper(cw, usedClasses) + classReader.accept(classRemapper, 0); + } + + +// static void remapClassNoRedefine2(ClassReader cr, UsedClasses4 usedClasses ) { +// ClassNode classNode = new ClassNode(); +// cr.accept(classNode, 0); +// +// classNode.methods.each { usedClasses.mapMethodDesc( it.desc)} +// classNode.fields.each { usedClasses.mapDesc( it.desc)} +// } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/AsmByteCodeVerifier.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/AsmByteCodeVerifier.groovy new file mode 100644 index 00000000..4600b4ff --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/AsmByteCodeVerifier.groovy @@ -0,0 +1,69 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.verifier + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.asmow2.AsmConsoleDecompiler +import org.objectweb.asm.ClassReader +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.MethodNode +import org.objectweb.asm.tree.analysis.Analyzer + +import java.util.logging.Logger; + +@CompileStatic +class AsmByteCodeVerifier { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ClassLoader classLoader1 + + + + public static boolean verifyByteCodeField = true + + AsmByteCodeVerifier(ClassLoader classLoader1) { + this.classLoader1 = classLoader1 + } + +/** may load class : @see org.objectweb.asm.tree.analysis.SimpleVerifier#isAssignableFrom + */ + // may be use org.objectweb.asm.util.CheckClassAdapter + ClassNode verifyByteCode(byte[] byteCode) { + if (!verifyByteCodeField) { + return null + } + ClassReader classReader = new ClassReader(byteCode); + ClassNode classNode = new ClassNode(); + classReader.accept(classNode, getParsingOptions()); + List methodNodes = classNode.methods + methodNodes.each { + MethodNode methodNode = it + if (methodNode.instructions.size() > 0) { +// log.info "checking : ${methodNode.name}" + try { + Analyzer analyzer = createAnalyzer(); + analyzer.analyze(classNode.name, methodNode); + } catch (Exception e) { + methodVerificationFailed(methodNode, byteCode, e) + } + } + } + return classNode; + } + + Analyzer createAnalyzer(){ + return new Analyzer(new JrrAsmVerifier(classLoader1)) + } + + int getParsingOptions(){ + return 0 + } + + + void methodVerificationFailed(MethodNode methodNode, byte[] byteCode, Exception e) { + String method2 = new AsmConsoleDecompiler().printMethod2(new ClassReader(byteCode), methodNode.name, true) + log.info "Verify failed in method : ${methodNode.name}: \n ${method2}" + throw new Exception("Verify failed in method : ${methodNode.name}", e) + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/DirByteCodeVerifier.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/DirByteCodeVerifier.groovy new file mode 100644 index 00000000..091ef671 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/DirByteCodeVerifier.groovy @@ -0,0 +1,53 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.verifier + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.asmow2.AsmUtils +import org.apache.commons.io.IOUtils +import org.zeroturnaround.zip.ZipEntryCallback +import org.zeroturnaround.zip.ZipUtil + +import java.util.logging.Logger +import java.util.zip.ZipEntry + +@CompileStatic +class DirByteCodeVerifier { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + AsmUtils asmUtils = new AsmUtils() + + AsmByteCodeVerifier asmByteCodeVerifier = new AsmByteCodeVerifier(getClass().getClassLoader()) + + void verifyDir(File dir) { + assert dir.exists() + assert dir.directory + dir.listFiles().toList().each { handleSubFile(it) } + } + + void handleSubFile(File f) { + if (f.isFile()) { + if (needCheckFile(f)) { + try { + asmByteCodeVerifier.verifyByteCode(f.bytes) + } catch (Exception e) { + log.info "failed verify ${f} : ${e}" + throw e + } + } + } else if (f.isDirectory()) { + if (needCheckDir(f)) { + verifyDir(f) + } + } + } + + boolean needCheckDir(File dir) { + return true + } + + boolean needCheckFile(File file) { + return file.name.endsWith('.class') + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/JarByteCodeVerifier.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/JarByteCodeVerifier.groovy new file mode 100644 index 00000000..91a000ff --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/JarByteCodeVerifier.groovy @@ -0,0 +1,43 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.verifier + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.asmow2.AsmUtils +import org.apache.commons.io.IOUtils +import org.zeroturnaround.zip.ZipEntryCallback +import org.zeroturnaround.zip.ZipUtil; + +import java.util.logging.Logger +import java.util.zip.ZipEntry; + +@CompileStatic +class JarByteCodeVerifier implements ZipEntryCallback { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + AsmUtils asmUtils = new AsmUtils() + + AsmByteCodeVerifier asmByteCodeVerifier = new AsmByteCodeVerifier(getClass().getClassLoader()) + + void verifyJar(File jar) { + assert jar.exists() + ZipUtil.iterate(jar, this) + } + + @Override + void process(InputStream inputStream, ZipEntry zipEntry) throws IOException { + if (needVerify(zipEntry)) { + byte[] array = IOUtils.toByteArray(inputStream) + String name = zipEntry.getName() + try { + asmByteCodeVerifier.verifyByteCode(array) + } catch (Exception e) { + log.info "failed verify : ${name} : ${e}" + throw e + } + } + } + + boolean needVerify(ZipEntry zipEntry) { + return zipEntry.getName().endsWith('.class') + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/JrrAsmVerifier.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/JrrAsmVerifier.groovy new file mode 100644 index 00000000..3d15d710 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/asmow2/verifier/JrrAsmVerifier.groovy @@ -0,0 +1,43 @@ +package net.sf.jremoterun.utilities.nonjdk.asmow2.verifier + +import groovy.transform.CompileStatic; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.analysis.SimpleVerifier; + +/** + * This verifier load classes during verification in method getClass(Type type) + */ +@CompileStatic +public class JrrAsmVerifier extends SimpleVerifier { + + ClassLoader classLoader1; + + JrrAsmVerifier(int api, Type currentClass, Type currentSuperClass, List currentClassInterfaces, boolean isInterface, ClassLoader classLoader1) { + super(api, currentClass, currentSuperClass, currentClassInterfaces, isInterface) + setClassLoader(classLoader1); + } + + public JrrAsmVerifier(ClassLoader classLoader1) { + this(org.objectweb.asm.Opcodes.ASM7, null, null, null, false, classLoader1); + + } + + @Override + void setClassLoader(ClassLoader loader) { + super.setClassLoader(loader) + this.classLoader1 = loader + } + + Class getClass(final Type type) { + Thread currentThread = Thread.currentThread() + ClassLoader classLoaderBefore = currentThread.getContextClassLoader() + try { + currentThread.setContextClassLoader(classLoader1) + return super.getClass(type) + } finally { + currentThread.setContextClassLoader(classLoaderBefore) + } + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/AndroidArchive.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/AndroidArchive.groovy new file mode 100644 index 00000000..db717f3c --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/AndroidArchive.groovy @@ -0,0 +1,23 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId; + +import java.util.logging.Logger; + +@CompileStatic +class AndroidArchive { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public MavenId m; + + AndroidArchive(MavenId m) { + this.m = m + } + + @Override + String toString() { + return "aar: " + m.toString() + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/CheckNonCache2.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/CheckNonCache2.groovy index ec67faba..b33bd45f 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/CheckNonCache2.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/CheckNonCache2.groovy @@ -15,12 +15,16 @@ abstract class CheckNonCache2 extends GroovyRunnerConfigurator2{ private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static String cacheFolderName = "cache"; + ClRef jfeeObject = new ClRef('org.jfree.data.ComparableObjectItem') ClRef ivyCl = new ClRef('org.sonatype.aether.RepositorySystem') ClassLoader cl = JrrClassUtils.currentClassLoader; + + static void check() { check(CheckNonCache2); } @@ -31,7 +35,7 @@ abstract class CheckNonCache2 extends GroovyRunnerConfigurator2{ } else { String string = location.toString(); - if (string==null||string.contains("cache")) { + if (string==null||string.contains(cacheFolderName)) { JrrUtilities.showException("Cached classes used : ${string}", new Exception("Cache used : ${string} for ${toCheck.name}")) } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/DefaultClasspathAdder.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/DefaultClasspathAdder.groovy index 1778d760..7ad7e879 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/DefaultClasspathAdder.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/DefaultClasspathAdder.groovy @@ -9,6 +9,7 @@ import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GroovyMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.Log4j2MavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.SshdMavenIds import java.util.logging.Logger @@ -17,13 +18,14 @@ import static net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds.g import static net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds.jline2 import static net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds.jline3 import static net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds.junit -import static net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds.sshd @CompileStatic class DefaultClasspathAdder extends InjectedCode { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static boolean addLatestFlag =false; + public static List findLatest = [] static { List l2 = findLatest @@ -46,12 +48,16 @@ class DefaultClasspathAdder extends InjectedCode { adder.addM guavaMavenId; adder.addM junit; adder.addAll GroovyMavenIds.all; - List findLatest3 = findLatest - findLatest3.each { - adder.addM(mcu.findLatestMavenOrGradleVersion2(it.m)) - }; + if(addLatestFlag) { + List findLatest3 = findLatest + findLatest3.each { + adder.addM(mcu.findLatestMavenOrGradleVersion2(it.m)) + }; + }else{ + adder.addAll(findLatest) + } adder.addMWithDependeciesDownload jline3 adder.addMWithDependeciesDownload jline2 - adder.addMWithDependeciesDownload sshd + adder.addMWithDependeciesDownload SshdMavenIds.core } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/GeneralBiblioRepository.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/GeneralBiblioRepository.groovy new file mode 100644 index 00000000..47af0023 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/GeneralBiblioRepository.groovy @@ -0,0 +1,56 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.mdep.ivy.IBiblioRepository; + +import java.util.logging.Logger; + +@CompileStatic +class GeneralBiblioRepository implements IBiblioRepository { + + public final String name; + public final String url; + + GeneralBiblioRepository(String name, String url) { + this.name = name + this.url = url + } + + @Override + String name() { + return name; + } + + String getUrl() { + return url + } + + @Override + String toString() { + return name + } + + boolean equals(o) { + if(o==null){ + return false + } + if (this.is(o)) return true + if (getClass() != o.class) return false + + GeneralBiblioRepository that = (GeneralBiblioRepository) o + + if (name != that.name) return false + if (url != that.url) return false + + return true + } + + int hashCode() { + int result + result = (name != null ? name.hashCode() : 0) + result = 31 * result + (url != null ? url.hashCode() : 0) + return result + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/IvyDepResolverSetter.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/IvyDepResolverSetter.groovy index f7c3ce5c..86a05f91 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/IvyDepResolverSetter.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/IvyDepResolverSetter.groovy @@ -1,7 +1,8 @@ package net.sf.jremoterun.utilities.nonjdk.classpath; import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.mdep.ivy.IvyDepResolver2; +import net.sf.jremoterun.utilities.mdep.ivy.IvyDepResolver2 +import net.sf.jremoterun.utilities.nonjdk.JavaVersionChecker; import java.util.logging.Logger; import groovy.transform.CompileStatic; @@ -15,6 +16,7 @@ class IvyDepResolverSetter implements Runnable{ @Override void run() { + JavaVersionChecker.checkJavaVersion(); IvyDepResolver2.setDepResolver() } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/MavenRepositoriesEnum.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/MavenRepositoriesEnum.groovy index 8f9eb59d..2e36306d 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/MavenRepositoriesEnum.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/MavenRepositoriesEnum.groovy @@ -7,15 +7,23 @@ import net.sf.jremoterun.utilities.mdep.ivy.IBiblioRepository enum MavenRepositoriesEnum implements IBiblioRepository{ // https://oss.sonatype.org/#view-repositories - groovy('https://dl.bintray.com/groovy/maven'), + jcenter('https://jcenter.bintray.com'), central('https://repo1.maven.org/maven2'), gradle('https://repo.gradle.org/gradle/libs-releases-local'), - androidGoogle('https://dl.google.com/dl/android/maven2'), + gradlePlugins('https://plugins.gradle.org/m2'), + androidGoogle('https://dl.google.com/dl/android/maven2'),// https://dl.google.com/dl/android/maven2/index.html + googleMirror('https://maven-central.storage-download.googleapis.com/repos/central/data/'), javassh('http://artifactory.javassh.com/public-releases'), eclipse('https://repo.eclipse.org/content/groups/releases'), jetbrainsIdea('https://www.jetbrains.com/intellij-repository/releases'), - sonatypeRelease('https://oss.sonatype.org/service/local/repositories/releases'), + sonatypeRelease( 'https://oss.sonatype.org/service/local/repositories/releases'), + sonatypeSnapshots('https://oss.sonatype.org/content/repositories/snapshots/'), + spring('https://repo.spring.io/plugins-release'), + mozilla('https://maven.mozilla.org/maven2'), + groovy('https://dl.bintray.com/groovy/maven'), + teamcityRestClient('https://dl.bintray.com/jetbrains/teamcity-rest-client'), + teamcity('https://download.jetbrains.com/teamcity-repository'), ; String url; diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/SshConsoleAdder.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/SshConsoleAdder.groovy index 5443d5b3..09db8ce0 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/SshConsoleAdder.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/SshConsoleAdder.groovy @@ -4,7 +4,8 @@ import groovy.transform.CompileStatic; import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.AddFileToClassloaderDummy -import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences; +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs; import java.util.logging.Logger; @@ -15,8 +16,9 @@ class SshConsoleAdder { static void addSshConsole(AddFilesToClassLoaderCommon adder) { adder.add GitReferences.sshConsole - File baseDir = GitReferences.sshConsole.specOnly.resolveToFile() - adder.add new File(baseDir, 'images') + adder.add GitSomeRefs.sshConsole.childL('images/') +// File baseDir = GitReferences.sshConsole.specOnly.resolveToFile() +// adder.add new File(baseDir, 'images') } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/UrlCLassLoaderUtils2.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/UrlCLassLoaderUtils2.groovy index ca6b85fc..86967e9c 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/UrlCLassLoaderUtils2.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/UrlCLassLoaderUtils2.groovy @@ -60,17 +60,26 @@ ${classPath} * return without tail */ static List getClassLocationAll2(final Class clazz) { - final String tail = clazz.getName().replace('.', '/') + ".class"; + final String tailJava = clazz.getName().replace('.', '/') + ".class"; + final String tailGroovy = clazz.getName().replace('.', '/') + ".groovy"; List urls = getClassLocationAll(clazz.getName(), clazz.getClassLoader()) + // log.info "urls = ${urls}" List files = urls.collect { - String asString = it.toString(); - asString = asString.substring(0, asString.length() - tail.length()); + final String asString1 = it.toString(); + String asString; + if (asString1.endsWith('.class')) { + asString = asString1.substring(0, asString1.length() - tailJava.length()); + } else if (asString1.endsWith('.groovy')) { + asString = asString1.substring(0, asString1.length() - tailGroovy.length()); + } else { + throw new UnsupportedOperationException("strange file : ${it}") + } if (asString.startsWith("jar:")) { asString = asString.substring(4, asString.length() - 2); - } URL url = new URL(asString) - return UrlToFileConverter.c.convert(url) + File res = UrlToFileConverter.c.convert(url) + return res } return files } @@ -141,6 +150,9 @@ ${classPath} */ static List getClassLocationAll(final String className, ClassLoader classLoader) throws MalformedURLException { + if(className == Class.getName()){ + throw new IllegalArgumentException("Strange class name : ${className}") + } final String tail = UrlCLassLoaderUtils.buildClassNameSuffix(className); if (classLoader == null) { log.info("class loaded by boot class loader : ${className}, finding any resource instead of all") diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/UserBintrayRepo.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/UserBintrayRepo.groovy new file mode 100644 index 00000000..2be0a4af --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/UserBintrayRepo.groovy @@ -0,0 +1,54 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.mdep.ivy.IBiblioRepository; + +import java.util.logging.Logger; + +@CompileStatic +class UserBintrayRepo implements IBiblioRepository{ + + public final String name; + + /** + * in format : 'jfrog/bintray-tools' + */ + UserBintrayRepo(String name) { + this.name = name + assert name.contains('/') + } + + @Override + String name() { + return name; + } + + @Override + String getUrl() { + return "https://dl.bintray.com/${name}" + } + + @Override + String toString() { + return name + } + + boolean equals(o) { + if(o==null){ + return false + } + if (this.is(o)) return true; + if (getClass() != o.getClass()) return false; + + UserBintrayRepo that = (UserBintrayRepo) o; + + if (name != that.name) return false; + return true + } + + int hashCode() { + return (name != null ? name.hashCode() : 0); + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorEnumConverter.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorEnumConverter.groovy new file mode 100644 index 00000000..5257e83f --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorEnumConverter.groovy @@ -0,0 +1,37 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers; + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.classpath.ClassPathCalculatorAbstract +import net.sf.jremoterun.utilities.classpath.ClassPathCalculatorWithAdder; +import net.sf.jremoterun.utilities.classpath.MavenId; +import net.sf.jremoterun.utilities.classpath.MavenIdContains; +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.AllMavenIdsRefs; + +import java.util.Map; + +@CompileStatic +public class ClassPathCalculatorEnumConverter extends ClassPathCalculatorSup2Groovy { + + AllMavenIdsRefs allMavenIdsRefs; + Map mavenIdMavenIdContainsMap; + + public ClassPathCalculatorEnumConverter(AllMavenIdsRefs allMavenIdsRefs) { + this.allMavenIdsRefs = allMavenIdsRefs; + mavenIdMavenIdContainsMap = allMavenIdsRefs.buildMapWithoutVersion() + } + + @Override + Object filterOnMavenId(MavenId mavenId, String group, String artifact) { + String mavenId1 = allMavenIdsRefs.convertMavenId(mavenId) + Object mavenIdContains1 = mavenIdMavenIdContainsMap.get(mavenId1) + if(mavenIdContains1==null){ + return mavenId; + } + return mavenIdContains1; + } + + @Override + Object transformMavenIdContains(MavenIdContains mavenIdContains) { + return mavenIdContains; + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorGroovyWise.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorGroovyWise.groovy index d31813bc..335afedb 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorGroovyWise.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorGroovyWise.groovy @@ -77,10 +77,10 @@ class ClassPathCalculatorGroovyWise extends ClassPathCalculatorGitRefSup { if (fileInMaven == null) { return mavenId } - String shainMaven = calcSha1ForFile(fileInMaven) + String shaInMaven = calcSha1ForFile(fileInMaven) - if (shainFile != shainMaven) { - onDifferentHashInFileAndInMavenFile(jarFile, fileInMaven, mavenId, shainFile, shainMaven) + if (shainFile != shaInMaven) { + onDifferentHashInFileAndInMavenFile(jarFile, fileInMaven, mavenId, shainFile, shaInMaven) return null } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorGroovyWithDownloadWise.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorGroovyWithDownloadWise.groovy index 7089c432..ef55f45d 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorGroovyWithDownloadWise.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorGroovyWithDownloadWise.groovy @@ -4,6 +4,8 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.BaseDirSetting import net.sf.jremoterun.utilities.nonjdk.classpath.repohash.File2HashMapJsonSaver import net.sf.jremoterun.utilities.nonjdk.classpath.search.FindMavenIdsAndDownload import net.sf.jremoterun.utilities.nonjdk.ideadep.LongTaskInfo @@ -24,16 +26,23 @@ class ClassPathCalculatorGroovyWithDownloadWise extends ClassPathCalculatorGroov // File noMavenIdConfigFile = MissedMavenIdsSettingsLoader.noMavenIdFilesDefault - public static File noMavenIdConfigJsonFile = new File(MavenDefaultSettings.mavenDefaultSettings.userHome, "jrr/configs/noMavenIds2.json") + public + static ToFileRef2 noMavenIdConfigJsonFile = BaseDirSetting.baseDirSetting.childL("configs/noMavenIds2.json") + + //public static File noMavenIdConfigJsonFile = new File(MavenDefaultSettings.mavenDefaultSettings.userHome, "jrr/configs/noMavenIds2.json") Map noMavenIds + ClassPathCalculatorGroovyWithDownloadWise() { + this(new LongTaskInfo()) + } + ClassPathCalculatorGroovyWithDownloadWise(LongTaskInfo longTaskInfo) { super(longTaskInfo) } static Map readNoMavenIdsFile(){ - return File2HashMapJsonSaver.readJson2(noMavenIdConfigJsonFile) + return File2HashMapJsonSaver.readJson2(noMavenIdConfigJsonFile.resolveToFile()) } void loadMissedMavenids() { @@ -63,10 +72,13 @@ class ClassPathCalculatorGroovyWithDownloadWise extends ClassPathCalculatorGroov } static void saveSettingMissingMaveIdsS(Map noMavenIds2){ + if(noMavenIds2==null){ + throw new NullPointerException('maven ids is null') + } if (noMavenIds2.size() > 0) { // log.info("no maven ids saved ${noMavenIdConfigFile}") // noMavenIdConfigFile.text = loader3.saveSettings(noMavenIds) - File2HashMapJsonSaver.saveToJson(noMavenIds2,noMavenIdConfigJsonFile) + File2HashMapJsonSaver.saveToJson(noMavenIds2,noMavenIdConfigJsonFile.resolveToFile()) } else { log.info "noMavenIds is empty" } @@ -79,8 +91,8 @@ class ClassPathCalculatorGroovyWithDownloadWise extends ClassPathCalculatorGroov if (file == null) { onMissingMavenId(mavenId) } else { - File canonicalFile = file.canonicalFile - if (canonicalFile.path != file.path) { + File canonicalFile = file.getCanonicalFile() + if (canonicalFile.getPath() != file.getPath()) { MavenId mavenId2 = mavenCommonUtils.detectMavenIdFromFileName(canonicalFile) if (mavenId2 == null) { throw new Exception("failed resolve maven id from file : ${canonicalFile.absolutePath}, which derived from maven id ${mavenId}") diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorSup2Groovy.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorSup2Groovy.groovy index a13ab343..372cb37e 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorSup2Groovy.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/ClassPathCalculatorSup2Groovy.groovy @@ -3,13 +3,16 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities3 +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy import net.sf.jremoterun.utilities.classpath.BinaryWithSource import net.sf.jremoterun.utilities.classpath.ClassPathCalculatorWithAdder import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains import net.sf.jremoterun.utilities.classpath.MavenPath import net.sf.jremoterun.utilities.groovystarter.ClasspathConfigurator import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams +import net.sf.jremoterun.utilities.nonjdk.langutils.ObjectStringComparator import net.sf.jremoterun.utilities.nonjdk.store.ObjectWriter import net.sf.jremoterun.utilities.nonjdk.store.Writer3 import net.sf.jremoterun.utilities.nonjdk.store.Writer4Sub @@ -18,16 +21,38 @@ import org.codehaus.groovy.runtime.MethodClosure import java.util.logging.Logger @CompileStatic -public class ClassPathCalculatorSup2Groovy extends ClassPathCalculatorWithAdder { - private static final Logger log = Logger.getLogger(JrrClassUtils.currentClass.name); +class ClassPathCalculatorSup2Groovy extends ClassPathCalculatorWithAdder { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); // static MethodClosure addFileMethod = (MethodClosure)ClassPathCalculatorSup2Groovy.&addF - static MethodClosure addMavenMethod = (MethodClosure)ClassPathCalculatorSup2Groovy.&addM + static MethodClosure addMavenMethod = (MethodClosure) AddFilesToClassLoaderCommon.&addM + + static MethodClosure addGenerecMethod = (MethodClosure)AddFilesToClassLoaderCommon.&add + + public String varName = 'b' - static MethodClosure addGenerecMethod = (MethodClosure)ClassPathCalculatorSup2Groovy.&add ObjectWriter objectWriter = new ObjectWriter() + Map mavenId2ObjectMap = [:] + + void addEnumMavenIdsMap(Class enumMavenIds){ + Object[] values = JrrClassUtils.invokeJavaMethod(enumMavenIds,'values') as Object[] + List list = values.toList() as List + list.collect{ + MavenId m = it.getM() + mavenId2ObjectMap.put(m,it) + } + } + + Object convertMavenIdToObject(MavenId mavenId){ + Object mapTo = mavenId2ObjectMap.get(mavenId) + if(mapTo==null){ + return mavenId + } + return mapTo; + } + String saveClassPath9() { assert filesAndMavenIds.size()>0 String classpath2= saveClassPath7(filesAndMavenIds) @@ -40,6 +65,9 @@ public class ClassPathCalculatorSup2Groovy extends ClassPathCalculatorWithAdder writer3.addCreatedAtHeader() } + void sortElements(){ + Collections.sort(filesAndMavenIds, new ObjectStringComparator()); + } void buildImport(Writer3 writer3){ @@ -59,6 +87,10 @@ public class ClassPathCalculatorSup2Groovy extends ClassPathCalculatorWithAdder // } Writer3 createWriter(){ + return createWriter2(); + } + + Writer4Sub createWriter2(){ return new Writer4Sub(); } @@ -68,22 +100,24 @@ public class ClassPathCalculatorSup2Groovy extends ClassPathCalculatorWithAdder buildHeader(writer3) buildImport(writer3) // writer3.body.addAll (buildVar(writer3)) - writer3.body.add "" as String + //writer3.body.add "" as String writer3.body.addAll( files.collect { return convertEl(it,writer3) }) return writer3.buildResult() } + + String convertEl(Object el,Writer3 writer3){ switch (el) { case { el instanceof MavenId }: MavenId mavenId1 = (MavenId) el; - return (String) "b.${addMavenMethod.method} new ${MavenId.simpleName} ( '${mavenId1}' )" + return (String) "${varName}.${addMavenMethod.method} new ${MavenId.getSimpleName()} ( '${mavenId1}' )" break; default: String s = objectWriter.writeObject(writer3, el) - return (String) "b.${addGenerecMethod.method} ${s}" + return (String) "${varName}.${addGenerecMethod.method} ${s}" } } @@ -120,5 +154,26 @@ public class ClassPathCalculatorSup2Groovy extends ClassPathCalculatorWithAdder assert file.length() > 2 } + void excludeFilesWithNames(List fileNamesToExclude){ + List filesAndMavenIds2 = new ArrayList() + filesAndMavenIds.each { + boolean needPass = false + if (it instanceof File) { + File file1= (File) it; + if(fileNamesToExclude.contains(file1.getName())){ + + }else{ + needPass = true + } + }else { + needPass = true + } + if(needPass){ + filesAndMavenIds2.add(it) + } + } + filesAndMavenIds = filesAndMavenIds2 + } + } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddFileWithSources.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddFileWithSources.groovy index 6881b348..0e1c61ef 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddFileWithSources.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddFileWithSources.groovy @@ -13,7 +13,11 @@ import net.sf.jremoterun.utilities.classpath.MavenCommonUtils import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.MavenFileType2 import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepo +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepoContains import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRefSelf +import net.sf.jremoterun.utilities.nonjdk.classpath.AndroidArchive import java.util.logging.Logger @@ -66,7 +70,13 @@ abstract class AddFileWithSources extends AddFilesToClassLoaderGroovy implements void addSourceF(File source) throws Exception { JrrUtilities3.checkFileExist(source) addSourceFImpl(source) - addedSourceFiles.add(source) + if(addedSourceFiles.contains(source)){ + if(isLogFileAlreadyAdded){ + log.info "source file already added ${source}" + } + }else { + addedSourceFiles.add(source) + } } @Override @@ -79,18 +89,24 @@ abstract class AddFileWithSources extends AddFilesToClassLoaderGroovy implements } - @Override - void addSourceM(MavenId mavenId) { - File source = mavenCommonUtilsForSources.findMavenOrGradle(mavenId) + + void addSourceM(MavenIdAndRepoContains mavenId) { + File source = addSourceMNoExceptionOnMissing(mavenId.getMavenIdAndRepo()) + if (source == null) { - source = onMissingMavenSource(mavenId) + throw new FileNotFoundException("Failed find source for ${mavenId}"); } + addSourceF(source) + } + + @Override + void addSourceM(MavenId mavenId) { + File source = addSourceMNoExceptionOnMissing(mavenId) + if (source == null) { throw new FileNotFoundException("Failed find source for ${mavenId}"); } -// if (fileTransformer.acceptFile(null, source, null)) { addSourceF(source) -// } } // why it is needed @@ -149,23 +165,66 @@ abstract class AddFileWithSources extends AddFilesToClassLoaderGroovy implements } + @Override + File addSourceMNoExceptionOnMissing(MavenId mavenId){ + File source = mavenCommonUtilsForSources.findMavenOrGradle(mavenId) + if (source == null) { + source = onMissingMavenSource(mavenId) + } + return source + } + + File addSourceMNoExceptionOnMissing(MavenIdAndRepo mavenId){ + File source = mavenCommonUtilsForSources.findMavenOrGradle(mavenId.m) + if (source == null) { + source = onMissingMavenSource(mavenId) + } + return source + } + + @Override void addM(MavenId artifact) throws IOException { File file = resolveMavenId(artifact); if (file == null) { throw new FileNotFoundException(artifact.toString()); } - File source = mavenCommonUtilsForSources.findMavenOrGradle(artifact); -// log.info "artifact : ${artifact} ${source}" + File source = addSourceMNoExceptionOnMissing(artifact); if (source == null) { - source = onMissingMavenSource(artifact); + log.info("no source for maven : " + artifact); } + addFileSourceHelper(file, source); + } + + @Override + void addM(MavenIdAndRepoContains artifact) throws IOException { + File file = resolveMavenId(artifact.getMavenIdAndRepo()); + if (file == null) { + throw new FileNotFoundException(artifact.toString()); + } + File source = addSourceMNoExceptionOnMissing(artifact.getMavenIdAndRepo()); if (source == null) { log.info("no source for maven : " + artifact); } addFileSourceHelper(file, source); } + File onMissingMavenSource(MavenIdAndRepo mavenId) { + if (!downloadSources) { + log.info("no source for ${mavenId}") + return null + } + try { + MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver.downloadSource(mavenId.m,mavenId.repo) + File sourceFile = mavenCommonUtilsForSources.findMavenOrGradle(mavenId.m) +// log.info "source for ${mavenId} found ${sourceFile != null}" + return sourceFile + } catch (Throwable e) { + log.info "failed donwload source for ${mavenId} ${e}" + return null + } + } + File onMissingMavenSource(MavenId mavenId) { if (!downloadSources) { log.info("no source for ${mavenId}") @@ -312,30 +371,63 @@ abstract class AddFileWithSources extends AddFilesToClassLoaderGroovy implements } } + void addAar(AndroidArchive androidArchive){ + addSourceM(androidArchive.m); + } + @Override void addSourceGeneric(Object object) { + // no : MavenPath, URL + // switch (object) { case { object == null }: throw new NullPointerException("object is null") case { object instanceof Collection }: throw new IllegalArgumentException("Collection : ${object}") - case { object instanceof String }: - String s = (String) object; - addSourceS(s) + case { object instanceof AndroidArchive }: + addAar(object as AndroidArchive) + break + case { object instanceof MavenId }: + MavenId m = (MavenId) object; + addSourceM(m) + break; + case { object instanceof MavenIdAndRepoContains }: + MavenIdAndRepoContains mavenId1 = (MavenIdAndRepoContains) object; + addSourceM(mavenId1); break; case { object instanceof File }: File f = (File) object; addSourceF(f) break; - - case { object instanceof MavenId }: - MavenId m = (MavenId) object; - addSourceM(m) + case { object instanceof URL }: + URL file = object as URL + addUrl(file) + break; + case { object instanceof String }: + String s = (String) object; + addSourceS(s) + break; + case { object instanceof BinaryWithSourceI }: + BinaryWithSourceI file = object as BinaryWithSourceI + List sources = file.resolveSource(); + if(sources==null){ + throw new NullPointerException("No source for ${file}") + } + if(sources.size()){ + throw new NullPointerException("Source size is null for ${file}") + } + sources.each { + addSourceF(it) + } break; case { object instanceof MavenIdContains }: MavenIdContains mavenId3 = object as MavenIdContains addSourceGeneric mavenId3.getM() break; + case { object instanceof ToFileRefSelf }: + ToFileRefSelf toFileRefSelf = object as ToFileRefSelf + addSourceF toFileRefSelf.resolveToFile() + break; default: CustomObjectHandler customObjectHandler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler if (customObjectHandler == null) { @@ -348,4 +440,7 @@ abstract class AddFileWithSources extends AddFilesToClassLoaderGroovy implements } } + + + } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddFileWithSourcesDummy.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddFileWithSourcesDummy.groovy new file mode 100644 index 00000000..bbb0c9ec --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddFileWithSourcesDummy.groovy @@ -0,0 +1,29 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.helpers + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class AddFileWithSourcesDummy extends AddFileWithSources{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + AddFileWithSourcesDummy() { + downloadSources = true + } + + @Override + void addLibraryWithSource(File binary, List source) throws Exception { + + } + + @Override + void addSourceFImpl(File source) throws Exception { + + } + + @Override + void addSourceS(String source) throws Exception { + + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddToAdderSelf.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddToAdderSelf.groovy new file mode 100644 index 00000000..fac81713 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/AddToAdderSelf.groovy @@ -0,0 +1,12 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.helpers + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon + +@CompileStatic +interface AddToAdderSelf { + + void addToAdder(AddFilesToClassLoaderCommon adder) + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/BinaryWithSource3.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/BinaryWithSource3.groovy new file mode 100644 index 00000000..ab5fbf0d --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/BinaryWithSource3.groovy @@ -0,0 +1,29 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.helpers + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.BinaryWithSource2 +import net.sf.jremoterun.utilities.classpath.ToFileRef2; + +import java.util.logging.Logger; + +@CompileStatic +class BinaryWithSource3 extends BinaryWithSource2{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + BinaryWithSource3(File binary, File source) { + this(new FileToFileRef(binary),new FileToFileRef(source)); + } + + BinaryWithSource3(File binary, ToFileRef2 source) { + this(new FileToFileRef(binary),source); + } + + BinaryWithSource3(ToFileRef2 binary, ToFileRef2 source) { + super(binary, source) + } + + BinaryWithSource3(ToFileRef2 binary, List source) { + super(binary, source) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ClassPathInit3.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ClassPathInit3.groovy index 44a17107..2b2f54d8 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ClassPathInit3.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ClassPathInit3.groovy @@ -10,7 +10,10 @@ import net.sf.jremoterun.utilities.groovystarter.runners.RunnableFactory import net.sf.jremoterun.utilities.groovystarter.runners.RunnableWithParamsFactory import net.sf.jremoterun.utilities.groovystarter.st.GroovyRunnerConfigurator import net.sf.jremoterun.utilities.javassist.codeinjector.InjectedCode -import net.sf.jremoterun.utilities.mdep.DropshipClasspath; +import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import net.sf.jremoterun.utilities.nonjdk.InfocationFrameworkStructure +import net.sf.jremoterun.utilities.nonjdk.JavaVersionChecker +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs; import java.util.logging.Logger; import groovy.transform.CompileStatic; @@ -60,6 +63,7 @@ class ClassPathInit3 extends InjectedCode{ if(inited){ log.info "already inited" }else { + JavaVersionChecker.checkJavaVersion(); boolean logFileAlreadyAdded = adder.isLogFileAlreadyAdded adder.isLogFileAlreadyAdded = false adder.addAll DropshipClasspath.allLibsWithoutGroovy @@ -67,6 +71,9 @@ class ClassPathInit3 extends InjectedCode{ RunnableFactory.runRunner ivyDepResolver RunnableWithParamsFactory.fromClass4(gitRefSupport, [adder, gitRepoBase]) + if(InfocationFrameworkStructure.ifDir==null) { + InfocationFrameworkStructure.ifDir = GitSomeRefs.ifFramework.resolveToFile() + } } } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/FileToFileRef.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/FileToFileRef.groovy index 2148bb55..81ce6027 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/FileToFileRef.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/FileToFileRef.groovy @@ -7,7 +7,7 @@ import net.sf.jremoterun.utilities.classpath.ToFileRef2 import java.util.logging.Logger @CompileStatic -class FileToFileRef implements ToFileRef2 { +class FileToFileRef implements ToFileRef2,ZeroOverheadFileRef { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); @@ -21,4 +21,9 @@ class FileToFileRef implements ToFileRef2 { File resolveToFile() { return file } + + @Override + String toString() { + return "${file}"; + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/MavenRetryDownloader.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/MavenRetryDownloader.groovy index b79fc3aa..fb9debb1 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/MavenRetryDownloader.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/MavenRetryDownloader.groovy @@ -6,6 +6,7 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenDependenciesResolver import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenPath +import net.sf.jremoterun.utilities.mdep.ivy.IBiblioRepository import java.util.logging.Logger @CompileStatic @@ -67,6 +68,11 @@ class MavenRetryDownloader implements MavenDependenciesResolver { } + @Override + List resolveAndDownloadDeepDependencies(MavenId mavenId, boolean downloadSource, boolean dep, IBiblioRepository repo) { + return resolveAndDownloadDeepDependencies(mavenId,downloadSource,dep) + } + @Override List resolveAndDownloadDeepDependencies(MavenId mavenId, boolean downloadSource, boolean dep) { int leftRetry = retryCount @@ -101,6 +107,11 @@ class MavenRetryDownloader implements MavenDependenciesResolver { } } + @Override + void downloadSource(MavenId mavenId, IBiblioRepository repo) { + downloadSource(mavenId) + } + @Override File getMavenLocalDir() { return impl.getMavenLocalDir(); diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/UnzipRef.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/UnzipRef.groovy new file mode 100644 index 00000000..d76a1401 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/UnzipRef.groovy @@ -0,0 +1,30 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.helpers + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.CustomObjectHandler +import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.classpath.ToFileRef2; + +import java.util.logging.Logger; + +@CompileStatic +class UnzipRef implements ToFileRef2{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public ToFileRef2 refToZip; + + UnzipRef(ToFileRef2 refToZip) { + this.refToZip = refToZip + } + + @Override + File resolveToFile() { + CustomObjectHandler handler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler + if(handler==null){ + throw new IllegalStateException("customObjectHandler was not set") + } + return handler.resolveToFile(this) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/UrlRef.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/UrlRef.groovy new file mode 100644 index 00000000..570dbe61 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/UrlRef.groovy @@ -0,0 +1,35 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.helpers + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.CustomObjectHandler +import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.sfdownloader.UrlProvided; + +import java.util.logging.Logger; + +@CompileStatic +class UrlRef implements ToFileRef2, UrlProvided{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public URL url; + + UrlRef(URL url) { + this.url = url + } + + @Override + File resolveToFile() { + CustomObjectHandler handler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler + if(handler==null){ + throw new IllegalStateException("customObjectHandler was not set") + } + return handler.resolveToFile(url) + } + + @Override + URL convertToUrl() { + return url + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ZeroOverheadFileRef.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ZeroOverheadFileRef.groovy new file mode 100644 index 00000000..06d13575 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ZeroOverheadFileRef.groovy @@ -0,0 +1,12 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.helpers + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.classpath.ToFileRef2; + +import java.util.logging.Logger; + +@CompileStatic +interface ZeroOverheadFileRef extends ToFileRef2{ + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/InitLogTracker.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/InitLogTracker.groovy new file mode 100644 index 00000000..af0dc023 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/InitLogTracker.groovy @@ -0,0 +1,86 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.inittracker + +import groovy.transform.CompileStatic +import net.sf.jremoterun.JrrUtils; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities + +import javax.management.MBeanServer +import javax.management.ObjectName +import java.util.logging.Level; +import java.util.logging.Logger; + +@CompileStatic +class InitLogTracker implements InitLogTrackerMBean{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static ObjectName defaultObjectName = new ObjectName('iff:type=initlogs') + public static InitLogTracker defaultTracker = new InitLogTracker(); + public Vector listItems = new Vector<>() + //public boolean passToLog = false; + public boolean passToSysout = false; + + static { + JrrClassUtils.addIgnoreClass(JrrClassUtils.getCurrentClass()) + } + + InitLogTracker() { + try { + MBeanServer beanServer = JrrUtils.findLocalMBeanServer(); + if (!beanServer.isRegistered(defaultObjectName)) { + beanServer.registerMBean(this, defaultObjectName) + } + }catch(Exception e){ + log.log(Level.SEVERE,"failed register initLogTracker",e); + } + } + + void setListItems(Vector listItems) { + this.listItems = listItems + } + + void addLog(String msg){ + LogItem logItem =new LogItem() + logItem.msg = msg + listItems.add(logItem) + if(passToSysout){ + println(msg) + } + } + + void addException(String msg,Throwable exception){ + LogItem logItem =new LogItem() + logItem.msg = msg + logItem.exception = exception + listItems.add(logItem) + println("${msg} ${exception}") + } + + + + @Override + Vector getListItems() { + return listItems + } + + @Override + String getParticularLogItemStringWithException(int i){ + return JrrUtils.exceptionToString(getParticularLogItem(i).exception) + } + + @Override + String getParticularLogItemString(int i){ + return getParticularLogItem(i).toString() + } + + @Override + LogItem getParticularLogItem(int i){ + return listItems.get(i) + } + + @Override + LogItem getLastLogItem(){ + return listItems.lastElement(); + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/InitLogTrackerMBean.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/InitLogTrackerMBean.groovy new file mode 100644 index 00000000..5090628b --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/InitLogTrackerMBean.groovy @@ -0,0 +1,19 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.inittracker + +import groovy.transform.CompileStatic +import net.sf.jremoterun.JrrUtils; + +@CompileStatic +interface InitLogTrackerMBean { + + Vector getListItems() + + String getParticularLogItemStringWithException(int i) + + String getParticularLogItemString(int i) + + LogItem getParticularLogItem(int i) + + LogItem getLastLogItem() + +} \ No newline at end of file diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/LogItem.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/LogItem.groovy new file mode 100644 index 00000000..3e2f8e2c --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/inittracker/LogItem.groovy @@ -0,0 +1,22 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.inittracker + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class LogItem implements Serializable{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + +// public String location; + public String msg; + public Throwable exception; + + @Override + String toString() { + if(exception==null){ + return msg; + } + return "${msg} ${exception}" + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AllMavenIdsRefs.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AllMavenIdsRefs.groovy new file mode 100644 index 00000000..7c1893b5 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AllMavenIdsRefs.groovy @@ -0,0 +1,74 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepo +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepoContains +import net.sf.jremoterun.utilities.classpath.MavenIdContains; + +import java.util.logging.Logger; + +@CompileStatic +class AllMavenIdsRefs { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static List refsEnumsDefault =(List)[ + LatestMavenIds,AntMavenIds,AsmOw,BouncyCastleMavenIds,CustObjMavenIds,DerbyMavenIds,GitMavenIds,Gradle5MavenIds, + GroovyMavenIds,KafkaMavenIds,KotlinMavenIds,Log4j2MavenIds,MavenMavenIds,MigLayoutMavenIds, + NettyMavenIds,NexusSearchMavenIds,Pi4j,ProguardMavenIds,SquirrelSqlMavenIds,SshdMavenIds,TwelvemonkeysImageioMavenIds, + ] + + public final List refsEnums1; + public List refsEnumsList; + + AllMavenIdsRefs() { + this(refsEnumsDefault) + } + + AllMavenIdsRefs(List refsEnums1) { + this.refsEnums1 = refsEnums1 + } + + List buildEnumList(){ + if(refsEnumsList==null) { + List collect1 = (List) refsEnums1.collect { JrrClassUtils.invokeJavaMethod(it, 'values') }; + List list1 = []; + collect1.each { list1.addAll(it.toList()) } + refsEnumsList = list1; + } + return refsEnumsList + } + + Map buildMapWithVersion(){ + Map res = [:] + buildEnumList().each {res.put(convertToMavenId(it), it)} + return res; + } + + + Map buildMapWithoutVersion(){ + Map res = [:] + Map version = buildMapWithVersion() + version.entrySet().each { + res.put(convertMavenId(it.key),it.value) + } + return res; + } + + MavenId convertToMavenId(Object object){ + if (object instanceof MavenIdContains) { + return object.m; + } + if (object instanceof MavenIdAndRepoContains) { + return object.mavenIdAndRepo.m; + } + throw new UnsupportedOperationException("${object}") + } + + String convertMavenId(MavenId m){ + return m.groupId+':'+m.artifactId; + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AntMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AntMavenIds.groovy index 89f6aef2..8170c9bf 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AntMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AntMavenIds.groovy @@ -4,9 +4,10 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider @CompileStatic -enum AntMavenIds implements MavenIdContains { +enum AntMavenIds implements MavenIdContains , EnumNameProvider{ ant, ant_antlr, @@ -28,5 +29,8 @@ enum AntMavenIds implements MavenIdContains { public static List all = (List) values().toList() - + @Override + String getCustomName() { + return m.artifactId + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AsmOw.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AsmOw.groovy new file mode 100644 index 00000000..6ac2e008 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/AsmOw.groovy @@ -0,0 +1,39 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +@CompileStatic +enum AsmOw implements MavenIdContains, ToFileRef2, EnumNameProvider { + asm_util, + asm_tree, + asm_test, + asm_commons, + asm_analysis, + asm, +// asm_deprecated, + ; + + + MavenId m; + + AsmOw() { + m = new MavenId('org.ow2.asm', name().replace('_','-'), '9.1'); + } + + public static List all = values().toList() + + @Override + File resolveToFile() { + return m.resolveToFile() + } + + @Override + String getCustomName() { + return m.artifactId; + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/BouncyCastleMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/BouncyCastleMavenIds.groovy index f78c84bb..df57eda3 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/BouncyCastleMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/BouncyCastleMavenIds.groovy @@ -3,9 +3,11 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider @CompileStatic -enum BouncyCastleMavenIds implements MavenIdContains { +enum BouncyCastleMavenIds implements MavenIdContains, EnumNameProvider, ToFileRef2 { bcprov_ext_debug_jdk15on, @@ -13,9 +15,14 @@ enum BouncyCastleMavenIds implements MavenIdContains { bcmail_jdk15on, bcpg_jdk15on, - bctls_jdk15on, +// bctls_jdk15on, bcpkix_jdk15on, bcprov_jdk15on, + + bctls_jdk15on, + bctls_jdk15to18, + bcprov_jdk15to18, + bcutil_jdk15to18, ; // war @@ -23,9 +30,19 @@ enum BouncyCastleMavenIds implements MavenIdContains { MavenId m; BouncyCastleMavenIds() { - m = new MavenId('org.bouncycastle', name().replace('_', '-'), '1.60'); + m = new MavenId('org.bouncycastle', name().replace('_', '-'), '1.69'); } public static List all = values().toList() + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/ComplexGitRefs.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/ComplexGitRefs.groovy index 13637479..b097e733 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/ComplexGitRefs.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/ComplexGitRefs.groovy @@ -8,7 +8,7 @@ import net.sf.jremoterun.utilities.nonjdk.git.ToFileRefRedirect @CompileStatic enum ComplexGitRefs implements ToFileRefRedirect { - eclipseGithubApiB(new BinaryWithSource2(LatestMavenIds.eclipseGitHubApi.m, GitReferences.eclipseGithubApi)); + eclipseGithubApiB(new BinaryWithSource2(MavenIdAndRepoCustom.eclipseGitHubApi, GitReferences.eclipseGithubApi)); ToFileRef2 ref diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/CustObjMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/CustObjMavenIds.groovy index 65f9d128..24364218 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/CustObjMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/CustObjMavenIds.groovy @@ -3,32 +3,33 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 @CompileStatic -enum CustObjMavenIds implements MavenIdContains { +public enum CustObjMavenIds implements MavenIdContains, ToFileRef2 { commnonsLang('commons-lang:commons-lang:2.6') - , git('org.eclipse.jgit:org.eclipse.jgit:5.1.2.201810061102-r') - //, git('org.eclipse.jgit:org.eclipse.jgit:4.5.4.201711221230-r') - , compressAbstraction('org.rauschig:jarchivelib:0.8.0') - , zeroTurnaroundZipUtil('org.zeroturnaround:zt-zip:1.13') - , junrar1('com.github.junrar:junrar:3.0.0') + , git(GitMavenIds.jgit.getM().toString()) + , compressAbstraction('org.rauschig:jarchivelib:1.1.0') + , zeroTurnaroundZipUtil('org.zeroturnaround:zt-zip:1.14') + , junrar1('com.github.junrar:junrar:7.4.0') , slf4jApi('org.slf4j:slf4j-api:1.7.25') , slf4jJdkLogger('org.slf4j:slf4j-jdk14:1.7.25') , commonsLoggingMavenId('commons-logging:commons-logging:1.2') - // use eclipseJavaAstParser - , eclipseJavaCompiler('org.eclipse.jdt:ecj:3.15.0') - , eclipseJavaAstParser('org.eclipse.jdt:org.eclipse.jdt.core:3.15.0') + , eclipseJavaCompiler('org.eclipse.jdt:ecj:3.24.0') + , eclipseJavaAstParser('org.eclipse.jdt:org.eclipse.jdt.core:3.24.0') + // TODO use eclipseJavaAstParser /** * 2.5 supports jdk 6+. * 2.6 supports 7+. + * in 2.8.0 FileUtils.Copy changed. Sometime throw error when override file */ , commonsIo('commons-io:commons-io:2.6') // svn deps , antlrRuntime('org.antlr:antlr-runtime:3.5.2') - , sequenceLibrary('de.regnis.q.sequence:sequence-library:1.0.3') - , sqljet('org.tmatesoft.sqljet:sqljet:1.1.11') - , svnKit('org.tmatesoft.svnkit:svnkit:1.9.3') + , sequenceLibrary('de.regnis.q.sequence:sequence-library:1.0.4') + , sqljet('org.tmatesoft.sqljet:sqljet:1.1.14') + , svnKit('org.tmatesoft.svnkit:svnkit:1.10.3') ; @@ -38,6 +39,11 @@ enum CustObjMavenIds implements MavenIdContains { this.m = new MavenId(m2) } + @Override + File resolveToFile() { + return m.resolveToFile() + } + public static List all = values().toList() } \ No newline at end of file diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/CustomRefsUrls.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/CustomRefsUrls.groovy new file mode 100644 index 00000000..03c3ed38 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/CustomRefsUrls.groovy @@ -0,0 +1,37 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.CustomObjectHandler +import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.nonjdk.sfdownloader.UrlProvided; + +import java.util.logging.Logger; + +@CompileStatic +enum CustomRefsUrls implements UrlProvided{ + + pureJavacommnyJetBrainsUrl('https://jetbrains.bintray.com/pty4j/org/jetbrains/pty4j/purejavacomm/0.0.11.1/purejavacomm-0.0.11.1.jar'), + ; + + + String url; + + CustomRefsUrls(String url) { + this.url = url + } + + @Override + URL convertToUrl() { + return new URL(url) + } + + @Override + File resolveToFile() { + CustomObjectHandler handler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler + if(handler==null){ + throw new IllegalStateException("customObjectHandler was not set") + } + return handler.resolveToFile(url) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/DerbyMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/DerbyMavenIds.groovy index 4ab1f8ed..39357c16 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/DerbyMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/DerbyMavenIds.groovy @@ -3,9 +3,10 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 @CompileStatic -enum DerbyMavenIds implements MavenIdContains { +enum DerbyMavenIds implements MavenIdContains, ToFileRef2 { derbyLocale_zh_TW, derbyLocale_zh_CN, derbyLocale_ru, @@ -36,4 +37,8 @@ enum DerbyMavenIds implements MavenIdContains { public static List all = values().toList() + @Override + File resolveToFile() { + return m.resolveToFile() + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitMavenIds.groovy new file mode 100644 index 00000000..97ee4867 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitMavenIds.groovy @@ -0,0 +1,50 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +@CompileStatic +enum GitMavenIds implements MavenIdContains, EnumNameProvider, ToFileRef2 { + + jgit_pgm, + jgit_ui, +// jgit_ssh_apache, // this requires sshd:2.2+ + jgit_ssh_jsch, + jgit_lfs_server, + jgit_lfs, + jgit_junit_ssh, + jgit_junit_http, + jgit_junit, + jgit_http_server, + jgit_http_apache, + jgit_gpg_bc, + jgit_archive, + jgit_ant, + jgit, + ; + + + MavenId m; + + GitMavenIds() { + String artifactId = 'org.eclipse.'+name().replace('_', '.') + m = new MavenId('org.eclipse.jgit', artifactId, '5.12.0.202106070339-r'); + } + + public static List all = values().toList() + + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitReferences.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitReferences.groovy index 482feb72..22b57afe 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitReferences.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitReferences.groovy @@ -1,6 +1,8 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.BinaryWithSource2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import net.sf.jremoterun.utilities.nonjdk.git.GitBinaryAndSourceRef import net.sf.jremoterun.utilities.nonjdk.git.GitRef import net.sf.jremoterun.utilities.nonjdk.git.GitSpec @@ -12,79 +14,85 @@ class GitReferences { // public static GitBinaryAndSourceRef jtermSsh = JeditermBinRefs.jtermSsh.ref // public static GitBinaryAndSourceRef jtermPty = JeditermBinRefs.jtermPty.ref - public static GitSpec jtermGitSpec = new GitSpec('https://github.com/JetBrains/jediterm') + // public static GitRef jtermSrc = new GitRef('https://github.com/JetBrains/jediterm', 'terminal/src') - public static GitRef pty4jLinuxLibs = new GitRef('https://github.com/traff/pty4j', 'os') - public static GitRef pty4jSrc = new GitRef('https://github.com/traff/pty4j', 'src') - public static GitRef purejavacommTraffSrc = new GitRef('https://github.com/traff/purejavacomm', 'src') + public static FileChildLazyRef pty4jLinuxLibs = GitSomeRefs.pty4jTraff.childL('os') + public static FileChildLazyRef pty4jSrc = GitSomeRefs.pty4jTraff.childL('src') + public static FileChildLazyRef pty4jJetbrainsSrc = GitSomeRefs.pty4jJetBrains.childL( 'src') + public static FileChildLazyRef purejavacommTraffSrc = GitSomeRefs.purejavacommTraff.childL( 'src') + public static FileChildLazyRef pureJavacommnyHolkuSrc = GitSomeRefs.purejavacommNyholku.childL( 'src') public - static GitBinaryAndSourceRef rsta = new GitBinaryAndSourceRef('https://github.com/venkato/RSTALanguageSupport', 'build/rsta.jar', 'src/main/java') + static GitBinaryAndSourceRef rsta = new GitBinaryAndSourceRef(GitSomeRefs.rstaVenkato, 'build/rsta.jar', 'src/main/java') public - static GitBinaryAndSourceRef javaDecompiler = new GitBinaryAndSourceRef('https://github.com/Konloch/bytecode-viewer', 'BytecodeViewer 2.9.8.jar', 'src/main/java') + static GitBinaryAndSourceRef javaDecompiler = new GitBinaryAndSourceRef(GitSomeRefs.javaDecompiler, 'BytecodeViewer 2.9.8.jar', 'src/main/java') public - static GitBinaryAndSourceRef rstaAutoCompetion = new GitBinaryAndSourceRef('https://github.com/venkato/AutoComplete', 'dist/AutoComplete.jar', 'src/main/java') - - public static GitSpec ifFramework = new GitSpec("https://github.com/venkato/InvocationFramework") + static GitBinaryAndSourceRef rstaAutoCompetion = new GitBinaryAndSourceRef(GitSomeRefs.rstaAutoCompetionVenkato, 'dist/AutoComplete.jar', 'src/main/java') - public static GitSpec starter = new GitSpec("https://github.com/venkato/starter3") - public static GitRef groovyRunner = new GitRef(starter, 'firstdownload/groovyrunner.groovy') + @Deprecated + public static FileChildLazyRef groovyRunner = JrrStarterJarRefs.groovyRunner - public static GitRef groovyClasspathDir = new GitRef(starter, 'libs/copy') + @Deprecated + public static FileChildLazyRef groovyClasspathDir = JrrStarterJarRefs.groovyClasspathDir - public static GitRef sshConsole = new GitRef("https://github.com/venkato/ssh-consoles", "src") + public static FileChildLazyRef sshConsole = GitSomeRefs.sshConsole.childL("src") - public static GitRef firstdownloadGitRef = new GitRef("https://github.com/venkato/firstdownload", "src") + public static FileChildLazyRef firstdownloadGitRef = GitSomeRefs.firstdownloadGitRef.childL( "src") - public static GitRef sshConsoleImages = new GitRef(sshConsole.repo, "images") + public static FileChildLazyRef sshConsoleImages = GitSomeRefs.sshConsole.childL( "images") - public static GitRef jnaplatext = new GitRef('https://github.com/malyn/jnaplatext', 'src') + public static FileChildLazyRef jnaplatext = GitSomeRefs.jnaplatext.childL( 'src') - public static GitSpec rdesktop = new GitSpec('https://github.com/kohsuke/properjavardp') public - static GitBinaryAndSourceRef socketGuiTest = new GitBinaryAndSourceRef('https://github.com/akshath/SocketTest', 'dist/SocketTest.jar', 'src') + static GitBinaryAndSourceRef socketGuiTest = new GitBinaryAndSourceRef(GitSomeRefs.socketGuiTest, 'dist/SocketTest.jar', 'src') public - static GitRef eclipseBatchCompiler = new GitRef("https://github.com/groovy/groovy-eclipse", "base/org.eclipse.jdt.groovy.core/src") + static FileChildLazyRef eclipseBatchCompiler = GitSomeRefs.eclipseBatchCompiler.childL( "base/org.eclipse.jdt.groovy.core/src") - public static GitRef helfySrc = new GitRef("https://github.com/xardazz/helfy", "src") + public static FileChildLazyRef helfySrc = GitSomeRefs.helfy.childL( "src") - public static GitRef helfyTest = new GitRef("https://github.com/xardazz/helfy", "test") + public static FileChildLazyRef helfyTest = GitSomeRefs.helfy.childL( "test") public - static GitRef eclipseFileCompiltion = new GitRef("https://github.com/impetuouslab/eclipse-filecompletion", "filecompletion/org.impetuouslab.eclipse.filecompletion/src") + static FileChildLazyRef eclipseFileCompiltion = GitSomeRefs.eclipseFileCompiltion.childL("filecompletion/org.impetuouslab.eclipse.filecompletion/src") - public static GitSpec jnaRepo = new GitSpec("https://github.com/venkato/jna") + public static FileChildLazyRef jschDocumentationRef = GitSomeRefs.jschDocumentationRef.childL('src/main/java') + public static BinaryWithSource2 jschDocumentationBinWithSrc = new BinaryWithSource2( LatestMavenIds.jcraft, jschDocumentationRef) public - static GitBinaryAndSourceRef jnaJvmti = new GitBinaryAndSourceRef(jnaRepo, 'build/jvmti.jar', 'src-jvmtiutils') + static GitBinaryAndSourceRef jnaJvmti = new GitBinaryAndSourceRef(GitSomeRefs.jnaRepo, 'build/jvmti.jar', 'src-jvmtiutils') + + public static GitBinaryAndSourceRef jnaCore = new GitBinaryAndSourceRef(GitSomeRefs.jnaRepo, 'build/jna_core.jar', 'jna/src') + + @Deprecated + public static GitRef jnaJvmtiResourcesDir = new GitRef (GitSomeRefs.jnaRepo.getGitSpec().repo,'jvmti-resources'); + public static FileChildLazyRef jnaJvmtiResourcesDir2 = GitSomeRefs.jnaRepo.childL( 'jvmti-resources') - public static GitBinaryAndSourceRef jnaCore = new GitBinaryAndSourceRef(jnaRepo, 'build/jna_core.jar', 'jna/src') - public static GitRef jnaJvmtiResourcesDir = new GitRef(jnaRepo, 'jvmti-resources') + public static FileChildLazyRef androidR8 = GitSomeRefs.androidR8.childL( 'src/main/java') - public static GitRef androidR8 = new GitRef('https://r8.googlesource.com/r8', 'src/main/java') + /** + * Used in {@link org.jna.jvmtiutils.JnaNativeMethods} + */ + @Deprecated + public static GitSpec jnaRepo = GitSomeRefs.jnaRepo.gitSpec - public static GitSpec jhexViewer = new GitSpec('https://github.com/google/binnavi') - // https://github.com/lbalazscs/Pixelitor - // https://github.com/statickidz/SimpleNotepad-Swing public - static GitRef eclipseGithubApi = new GitRef('https://github.com/eclipse/egit-github', 'org.eclipse.egit.github.core/src') + static FileChildLazyRef eclipseGithubApi = GitSomeRefs.eclipseGithubApi.childL( 'org.eclipse.egit.github.core/src') - public static GitSpec dockingFrames = new GitSpec('https://github.com/Benoker/DockingFrames') } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitSomeRefs.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitSomeRefs.groovy new file mode 100644 index 00000000..9cc0cfb9 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitSomeRefs.groovy @@ -0,0 +1,96 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.BinaryWithSource2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef +import net.sf.jremoterun.utilities.nonjdk.git.GitBinaryAndSourceRef +import net.sf.jremoterun.utilities.nonjdk.git.GitRef +import net.sf.jremoterun.utilities.nonjdk.git.GitRefRef +import net.sf.jremoterun.utilities.nonjdk.git.GitSpec +import net.sf.jremoterun.utilities.nonjdk.git.GitSpecRef; + +import java.util.logging.Logger; + +@CompileStatic +enum GitSomeRefs implements GitSpecRef { + + jtermGitSpec('https://github.com/JetBrains/jediterm'), + + pty4jTraff('https://github.com/traff/pty4j'), + pty4jJetBrains('https://github.com/JetBrains/pty4j'), + purejavacommTraff('https://github.com/traff/purejavacomm'), + purejavacommNyholku('https://github.com/nyholku/purejavacomm'), + + rstaVenkato('https://github.com/venkato/RSTALanguageSupport'), + + javaDecompiler('https://github.com/Konloch/bytecode-viewer'), + + + rstaAutoCompetionVenkato('https://github.com/venkato/AutoComplete'), + + ifFramework("https://github.com/venkato/InvocationFramework"), + + starter("https://github.com/venkato/starter3"), + + sshConsole("https://github.com/venkato/ssh-consoles"), + + firstdownloadGitRef("https://github.com/venkato/firstdownload"), + + + jnaplatext('https://github.com/malyn/jnaplatext'), + + + ideaPsiViewer('https://github.com/cmf/psiviewer'), + + rdesktop('https://github.com/kohsuke/properjavardp'), + + socketGuiTest('https://github.com/akshath/SocketTest'), + + eclipseBatchCompiler("https://github.com/groovy/groovy-eclipse"), + + helfy("https://github.com/xardazz/helfy"), + + eclipseFileCompiltion("https://github.com/impetuouslab/eclipse-filecompletion"), + + + jnaRepo("https://github.com/venkato/jna"), + + jschDocumentationRef("https://github.com/ePaul/jsch-documentation"), + + androidR8('https://r8.googlesource.com/r8'), + + jhexViewer('https://github.com/google/binnavi'), + + // https://github.com/lbalazscs/Pixelitor + // https://github.com/statickidz/SimpleNotepad-Swing + + eclipseGithubApi('https://github.com/eclipse/egit-github'), + + dockingFrames('https://github.com/Benoker/DockingFrames'), + + ideaDatabaseNavigator('https://bitbucket.org/dancioca/dbn'), + + mavenWagon('https://github.com/apache/maven-wagon'), + + asyncProfiler('https://github.com/jvm-profiling-tools/async-profiler'), + + ; + + GitSpec gitSpec; + + GitSomeRefs(String url) { + this.gitSpec = new GitSpec() + gitSpec.repo = url + } + + @Override + File resolveToFile() { + return getGitSpec().resolveToFile() + } + + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this, child); + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitlabLibsMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitlabLibsMavenIds.groovy new file mode 100644 index 00000000..0a4d08fe --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GitlabLibsMavenIds.groovy @@ -0,0 +1,86 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId; + +import java.util.logging.Logger; + +@CompileStatic +interface GitlabLibsMavenIds { + +// new MavenId('com.fasterxml.jackson.core:jackson-annotations:2.12.2'), +// new MavenId('com.fasterxml.jackson.core:jackson-core:2.12.2'), +// new MavenId('com.fasterxml.jackson.core:jackson-databind:2.12.2'), +// new MavenId('com.fasterxml.jackson.jaxrs:jackson-jaxrs-base:2.12.2'), +// new MavenId('com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.12.2'), +// new MavenId('com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.12.2'), +// new MavenId('commons-codec:commons-codec:1.11'), +// new MavenId('commons-logging:commons-logging:1.2'), +// new MavenId('jakarta.activation:jakarta.activation-api:1.2.2'), +// new MavenId('jakarta.annotation:jakarta.annotation-api:1.3.5'), +// new MavenId('jakarta.servlet:jakarta.servlet-api:4.0.3'), +// new MavenId('jakarta.ws.rs:jakarta.ws.rs-api:2.1.6'), +// new MavenId('jakarta.xml.bind:jakarta.xml.bind-api:2.3.2'), +// new MavenId('org.apache.httpcomponents:httpclient:4.5.9'), +// new MavenId('org.apache.httpcomponents:httpcore:4.4.11'), +// new MavenId('org.gitlab4j:gitlab4j-api:4.15.7'), +// new MavenId('org.glassfish.hk2.external:aopalliance-repackaged:2.6.1'), +// new MavenId('org.glassfish.hk2.external:jakarta.inject:2.6.1'), +// new MavenId('org.glassfish.hk2:hk2-api:2.6.1'), +// new MavenId('org.glassfish.hk2:hk2-locator:2.6.1'), +// new MavenId('org.glassfish.hk2:hk2-utils:2.6.1'), +// new MavenId('org.glassfish.hk2:osgi-resource-locator:1.0.3'), +// new MavenId('org.glassfish.jersey.connectors:jersey-apache-connector:2.30.1'), +// new MavenId('org.glassfish.jersey.core:jersey-client:2.30.1'), +// new MavenId('org.glassfish.jersey.core:jersey-common:2.30.1'), +// new MavenId('org.glassfish.jersey.inject:jersey-hk2:2.30.1'), +// new MavenId('org.glassfish.jersey.media:jersey-media-multipart:2.30.1'), +// new MavenId('org.jvnet.mimepull:mimepull:1.9.11'), + + MavenId coreLib = new MavenId('org.gitlab4j:gitlab4j-api:4.17.0'); + + List fastXmlsOthers = [ + new MavenId('com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.12.2'), + new MavenId('com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.2'), + new MavenId('com.fasterxml.jackson.datatype:jackson-datatype-joda:2.12.2'), + new MavenId('com.fasterxml.woodstox:woodstox-core:6.0.1'), + ] + + List fastXmls = [ + new MavenId('com.fasterxml.jackson.core:jackson-annotations:2.12.2'), + new MavenId('com.fasterxml.jackson.core:jackson-core:2.12.2'), + new MavenId('com.fasterxml.jackson.core:jackson-databind:2.12.2'), + new MavenId('com.fasterxml.jackson.jaxrs:jackson-jaxrs-base:2.12.2'), + new MavenId('com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.12.2'), + new MavenId('com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.12.2'), + ]; + + + List glassfish = [ + new MavenId('org.glassfish.hk2.external:aopalliance-repackaged:2.6.1'), + new MavenId('org.glassfish.hk2.external:jakarta.inject:2.6.1'), + new MavenId('org.glassfish.hk2:hk2-api:2.6.1'), + new MavenId('org.glassfish.hk2:hk2-locator:2.6.1'), + new MavenId('org.glassfish.hk2:hk2-utils:2.6.1'), + new MavenId('org.glassfish.hk2:osgi-resource-locator:1.0.3'), + new MavenId('org.glassfish.jersey.connectors:jersey-apache-connector:2.30.1'), + new MavenId('org.glassfish.jersey.core:jersey-client:2.30.1'), + new MavenId('org.glassfish.jersey.core:jersey-common:2.30.1'), + new MavenId('org.glassfish.jersey.inject:jersey-hk2:2.30.1'), + new MavenId('org.glassfish.jersey.media:jersey-media-multipart:2.30.1'), + new MavenId('org.jvnet.mimepull:mimepull:1.9.11'), + ]; + + + MavenId jakartaWsRsApi = new MavenId('jakarta.ws.rs:jakarta.ws.rs-api:2.1.6'); + + List jakarta = [ + new MavenId('jakarta.activation:jakarta.activation-api:1.2.2'), + new MavenId('jakarta.annotation:jakarta.annotation-api:1.3.5'), + new MavenId('jakarta.servlet:jakarta.servlet-api:4.0.3'), + jakartaWsRsApi, + new MavenId('jakarta.xml.bind:jakarta.xml.bind-api:2.3.2'), + ]; + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Gradle5MavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Gradle5MavenIds.groovy new file mode 100644 index 00000000..6b25b6f2 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Gradle5MavenIds.groovy @@ -0,0 +1,141 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommonDummy +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepo +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepoContains +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.MavenRepositoriesEnum +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +import java.util.logging.Logger + +@CompileStatic +enum Gradle5MavenIds implements MavenIdAndRepoContains, EnumNameProvider, ToFileRef2 { +// announce, + antlr, + api_metadata, + architecture_test, + base_services, + base_services_groovy, + bootstrap, + build_cache, + build_cache_http, + build_cache_packaging, +// build_comparison, + build_init, + build_option, + build_profile, + cli, + code_quality, + composite_builds, + core, + core_api, + dependency_management, + diagnostics, + docs, + ear, + execution, + file_collections, + files, + hashing, + ide, + ide_native, + ide_play, + installation_beacon, + instant_execution, + ivy, + jacoco, + javascript, + jvm_services, + kotlin_dsl, + kotlin_dsl_provider_plugins, + kotlin_dsl_tooling_builders, + kotlin_dsl_tooling_models, + language_groovy, + language_java, + language_jvm, + language_native, + language_scala, + launcher, + logging, + maven, + messaging, + model_core, + model_groovy, + //native, +// osgi, + persistent_cache, + pineapple, + platform_base, + platform_jvm, + platform_native, + platform_play, + plugin_development, + plugin_use, + plugins, + process_services, + publish, + reporting, + resources, + resources_gcs, + resources_http, + resources_s3, + resources_sftp, + runtime_api_info, + scala, + signing, + smoke_test, + snapshots, + soak, + test_kit, + testing_base, + testing_junit_platform, + testing_jvm, + testing_native, + tooling_api, + tooling_api_builders, + tooling_native, + version_control, + worker_processes, + workers, + wrapper, + + ; + + + MavenId m; + + + Gradle5MavenIds() { + String artifactId = 'gradle-' + name().replace('_', '-') + m = new MavenId('org.gradle', artifactId, '6.1.1');// '5.6.3' + } + + public static List all = values().toList() + + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + AddFilesToClassLoaderCommonDummy classLoaderCommonDummy = new AddFilesToClassLoaderCommonDummy() + classLoaderCommonDummy.addM( this); + if (classLoaderCommonDummy.addedFiles2.size() == 0) { + throw new FileNotFoundException(this.toString()) + } + return classLoaderCommonDummy.addedFiles2[0] +// return m.resolveToFile() + } + + @Override + MavenIdAndRepo getMavenIdAndRepo() { + return new MavenIdAndRepo(m, MavenRepositoriesEnum.gradle); + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GroovyMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GroovyMavenIds.groovy index 2ef17d01..21ee4577 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GroovyMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/GroovyMavenIds.groovy @@ -3,13 +3,31 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider @CompileStatic -enum GroovyMavenIds implements MavenIdContains { +enum GroovyMavenIds implements MavenIdContains, EnumNameProvider, ToFileRef2 { // groovy_all, groovy_binary,groovy,groovy_backports_compat23,groovy_all_minimal, - console, swing, nio, jsr223, sql, docgenerator, servlet, test, xml, json, groovysh, groovydoc, templates, ant, bsf, jmx, testng, + console, + swing, + nio, + jsr223, + sql, + docgenerator, + servlet, + test, + xml, + json, + groovysh,// + groovydoc, + templates, + ant, + bsf, + jmx, + testng, // macro, // tests_vm8, // performance, @@ -33,4 +51,13 @@ enum GroovyMavenIds implements MavenIdContains { public static List all = (List) values().toList() + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JeditermBinRefs.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JeditermBinRefs.groovy index a0307c7d..bbad6886 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JeditermBinRefs.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JeditermBinRefs.groovy @@ -1,22 +1,24 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import net.sf.jremoterun.utilities.nonjdk.git.GitBinaryAndSourceRef import net.sf.jremoterun.utilities.nonjdk.git.GitBinaryAndSourceRefRef import net.sf.jremoterun.utilities.nonjdk.git.GitSpec +import net.sf.jremoterun.utilities.nonjdk.git.GitSpecRef @Deprecated @CompileStatic enum JeditermBinRefs implements GitBinaryAndSourceRefRef { - jtermSsh(GitReferences.jtermGitSpec,'build/jediterm-ssh-2.8.jar', 'ssh/src') + jtermSsh(GitSomeRefs.jtermGitSpec,'build/jediterm-ssh-2.8.jar', 'ssh/src') // , jtermPty(GitReferences.jtermGitSpec,'build/jediterm-pty-2.10.jar', 'pty/src') // ,pty4j ('https://github.com/traff/pty4j', 'build/pty4j-0.7.5.jar', 'build/pty4j-0.7.5-src.jar') ; GitBinaryAndSourceRef ref; - JeditermBinRefs(GitSpec repo, String bin, String src) { + JeditermBinRefs(GitSpecRef repo, String bin, String src) { ref = new GitBinaryAndSourceRef(repo, bin, src) } @@ -31,4 +33,12 @@ enum JeditermBinRefs implements GitBinaryAndSourceRefRef { public static List all = values().toList() + + + + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this,child) + } + } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JeditermBinRefs2.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JeditermBinRefs2.groovy index c99ec4a0..cfe74d06 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JeditermBinRefs2.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JeditermBinRefs2.groovy @@ -1,6 +1,7 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import net.sf.jremoterun.utilities.nonjdk.git.GitBinaryAndSourceRef import net.sf.jremoterun.utilities.nonjdk.git.GitBinaryAndSourceRefRef import net.sf.jremoterun.utilities.nonjdk.git.GitRef @@ -17,7 +18,7 @@ enum JeditermBinRefs2 implements GitRefRef { GitRef ref; JeditermBinRefs2() { - ref = new GitRef(GitReferences.jtermGitSpec, name()+'/src') + ref = new GitRef(GitSomeRefs.jtermGitSpec, name()+'/src') } @Override @@ -27,4 +28,12 @@ enum JeditermBinRefs2 implements GitRefRef { public static List all = values().toList() + + + + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this,child) + } + } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterJarRefs.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterJarRefs.groovy index d311e38c..2dd1e782 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterJarRefs.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterJarRefs.groovy @@ -1,6 +1,8 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs; import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.BinaryWithSource2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import net.sf.jremoterun.utilities.nonjdk.git.GitRef import net.sf.jremoterun.utilities.nonjdk.git.GitRefRef; @@ -11,10 +13,14 @@ import groovy.transform.CompileStatic; @CompileStatic class JrrStarterJarRefs { - public static GitRef jremoterun = new GitRef(GitReferences.starter,"libs/origin/jremoterun.jar") + public static BinaryWithSource2 jrrutilitiesOneJar = new BinaryWithSource2(GitSomeRefs.starter.childL( "onejar/jrrutilities.jar"), JrrStarterProjects.JrrUtilities.getSrcRef()); + + + public static FileChildLazyRef groovyRunner = GitSomeRefs.starter.childL('firstdownload/groovyrunner.groovy') + + public static FileChildLazyRef groovyClasspathDir = GitSomeRefs.starter.childL('libs/copy') + - public static GitRef jrrassist = new GitRef(GitReferences.starter,"libs/origin/jrrassist.jar") -// public static GitRef jrrutilities = new GitRef(GitReferences.starter,"onejar/jrrutilities.jar") } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterJarRefs2.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterJarRefs2.groovy new file mode 100644 index 00000000..0c28cae3 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterJarRefs2.groovy @@ -0,0 +1,34 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef +import net.sf.jremoterun.utilities.nonjdk.git.ToFileRefRedirect + +@CompileStatic +enum JrrStarterJarRefs2 implements ToFileRefRedirect { + + jremoterun, jrrassist, groovy_custom, groovy, + ; + + + public FileChildLazyRef ref; + + JrrStarterJarRefs2() { + ref = GitSomeRefs.starter.childL('libs/copy/' + name() + '.jar') + } + + String getJarName(){ + return name() + '.jar'; + } + + @Override + ToFileRef2 getRedirect() { + ref; + } + + @Override + File resolveToFile() { + return ref.resolveToFile() + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterProjects.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterProjects.groovy index 3e4f9675..be4ee512 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterProjects.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/JrrStarterProjects.groovy @@ -2,30 +2,52 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences import net.sf.jremoterun.utilities.nonjdk.git.GitRef import net.sf.jremoterun.utilities.nonjdk.git.GitRefRef @CompileStatic -enum JrrStarterProjects implements GitRefRef { +enum JrrStarterProjects implements ChildFileLazy, ToFileRef2 { firstdownload, JrrInit, JrrStarter, JrrUtilities, ; - @Override + FileChildLazyRef refFile3; + + JrrStarterProjects() { + refFile3 = GitSomeRefs.starter.childL(name()); + } + + @Deprecated GitRef getRef() { - return new GitRef(GitReferences.starter,this.name()) + return new GitRef(GitSomeRefs.starter,this.name()) } @Override File resolveToFile() { - return getRef().resolveToFile() + return refFile3.resolveToFile() + } + + + FileChildLazyRef getSrcRef(){ + return refFile3.childL('src') } + + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this,child) + } + + static void addAll(AddFilesToClassLoaderCommon adder){ values().toList().each { - adder.add it.resolveToFile().child('src') + adder.add getSrcRef() } } + } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/KafkaMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/KafkaMavenIds.groovy new file mode 100644 index 00000000..aa25cddf --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/KafkaMavenIds.groovy @@ -0,0 +1,56 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +@CompileStatic +enum KafkaMavenIds implements MavenIdContains, EnumNameProvider, ToFileRef2 { + connect__api, + connect__basic__auth__extension, + connect__file, + connect__json, + connect__runtime, + connect__transforms, +// kafka_2___11, + kafka_2___12, + kafka__clients, + kafka__examples, + kafka__log4j__appender, + kafka__streams, + kafka__streams__examples, +// kafka__streams__scala_2___11, + kafka__streams__scala_2___12, + kafka__streams__test__utils, + kafka__tools, + +// streams__quickstart__java, +// streams__quickstart, + ; + + + MavenId m; + + KafkaMavenIds() { + String artifactId = name().replace('___', '.') + artifactId = artifactId .replace('__', '-') + m = new MavenId('org.apache.kafka', artifactId, '2.2.1'); + } + + public static List all = values().toList() + + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/KotlinMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/KotlinMavenIds.groovy new file mode 100644 index 00000000..ff729388 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/KotlinMavenIds.groovy @@ -0,0 +1,103 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider; + +import java.util.logging.Logger; + +@CompileStatic +enum KotlinMavenIds implements MavenIdContains, ToFileRef2, EnumNameProvider { + allopen, + android_extensions, + android_extensions_runtime, + annotation_processing, + annotation_processing_embeddable, + annotation_processing_gradle, + annotation_processing_maven, + annotation_processing_runtime, + annotations_android, + annotations_jvm, + build_common, + compiler, + compiler_client_embeddable, + compiler_embeddable, + compiler_runner, + daemon, + daemon_client, + daemon_client_new, + daemon_embeddable, + gradle_plugin, + gradle_plugin_api, + gradle_plugin_model, + main_kts, + maven_allopen, + maven_noarg, + maven_sam_with_receiver, + maven_serialization, + //native_library_reader, + native_utils, + noarg, + osgi_bundle, + reflect, + sam_with_receiver, + sam_with_receiver_compiler_plugin, + script_runtime, + script_util, + scripting_common, + scripting_compiler, + scripting_compiler_embeddable, + scripting_compiler_impl, + scripting_compiler_impl_embeddable, + scripting_intellij, + scripting_jsr223, + //scripting_jsr223_embeddable, + scripting_jvm, + scripting_jvm_host, + //scripting_jvm_host_embeddable, + serialization, + serialization_unshaded, + //source_sections_compiler_plugin, + stdlib, + stdlib_common, + stdlib_jdk7, + stdlib_jdk8, + stdlib_js, + test, + test_annotations_common, + test_common, + test_js, + test_junit, + test_junit5, + //test_nodejs_runner, + test_testng, + util_io, + util_klib, + ; + + + MavenId m; + + KotlinMavenIds() { + String artifactId = 'kotlin-'+name().replace('_','-') + m = new MavenId('org.jetbrains.kotlin', artifactId, '1.4.32'); + } + + public static List all = values().toList() + + @Override + File resolveToFile() { + return m.resolveToFile() + } + + @Override + String getCustomName() { + return m.artifactId; + } + + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/LatestMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/LatestMavenIds.groovy index 863e4043..0177b6d8 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/LatestMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/LatestMavenIds.groovy @@ -4,113 +4,123 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.MavenCommonUtils import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 import net.sf.jremoterun.utilities.mdep.DropshipClasspath + +// https://www.scilab.org/ looks nice, but how real use ? +// https://github.com/openimaj/openimaj image utils +// https://github.com/validator/galimatias url parser +// http://jeuclid.sourceforge.net/ math formala display +// https://github.com/atteo/classindex +// swing table with filter http://www.glazedlists.com/propaganda/features +// https://github.com/bytedeco/javacpp-presets +// db changes appliedr : https://github.com/antonnazarov/apricot @CompileStatic -enum LatestMavenIds implements MavenIdContains { +enum LatestMavenIds implements MavenIdContains, ToFileRef2 { // https://github.com/Sciss/DockingFrames log4jOld('log4j:log4j:1.2.17') , gnuGetOpt('gnu.getopt:java-getopt:1.0.13') , - @Deprecated - git(CustObjMavenIds.git), - @Deprecated zeroTurnaroundZipUtil(CustObjMavenIds.zeroTurnaroundZipUtil), - @Deprecated slf4jApi(CustObjMavenIds.slf4jApi), - @Deprecated commonsLoggingMavenId(CustObjMavenIds.commonsLoggingMavenId), - @Deprecated xmlApiId(DropshipClasspath.xmlApis), - @Deprecated commnonsLang(CustObjMavenIds.commnonsLang), - @Deprecated + //why jdom deprecated ? jdom('org.jdom:jdom:1.1'), - @Deprecated junrar1(CustObjMavenIds.junrar1), - @Deprecated compressAbstraction(CustObjMavenIds.compressAbstraction) - , swtWin('org.eclipse.platform:org.eclipse.swt.win32.win32.x86_64:3.108.0') - , eclipseWorkbench('org.eclipse.platform:org.eclipse.ui.workbench:3.112.0') + , swtWin('org.eclipse.platform:org.eclipse.swt.win32.win32.x86_64:3.116.0') + , eclipseWorkbench('org.eclipse.platform:org.eclipse.ui.workbench:3.122.100') , awsS3('com.amazonaws:aws-java-sdk-s3:1.11.275') - , jnrJffi('com.github.jnr:jffi:1.2.17') + , jnrJffi('com.github.jnr:jffi:1.3.2') , jniCodeGenerator('org.fusesource.hawtjni:hawtjni-example:1.16') - , sshd('org.apache.sshd:sshd-core:2.1.0') , // use eclipseJavaAstParser eclipseJavaCompiler(CustObjMavenIds.eclipseJavaCompiler) - , eclipseJavaAstParser(CustObjMavenIds.eclipseJavaAstParser) + , eclipseJavaAstParser(CustObjMavenIds.eclipseJavaAstParser) // eclipseJavaCompiler('org.eclipse.jdt.core.compiler:ecj:4.6.1') , logbackClassic('ch.qos.logback:logback-classic:1.2.3') , logbackCore('ch.qos.logback:logback-core:1.2.3') - , icu4j('com.ibm.icu:icu4j:63.1') - , jodaTime('joda-time:joda-time:2.10') + , icu4j('com.ibm.icu:icu4j:65.1') + , jodaTime('joda-time:joda-time:2.10.10') , junit('junit:junit:4.12') , rstaui("com.fifesoft:rstaui:2.6.1") , rstaAutoComplete("com.fifesoft:autocomplete:2.6.1") , fifeRtext("com.fifesoft.rtext:fife.common:2.6.3") , rstaLangSupport("com.fifesoft:languagesupport:2.6.0") , rsyntaxtextarea("com.fifesoft:rsyntaxtextarea:2.6.1") - , jna("net.java.dev.jna:jna:4.5.2") - , jnaPlatform("net.java.dev.jna:jna-platform:4.5.2") + , jna("net.java.dev.jna:jna:5.7.0") + , jnaPlatform("net.java.dev.jna:jna-platform:5.7.0") , jline2('jline:jline:2.12') , jline3('org.jline:jline:3.9.0') + , zip4j('net.lingala.zip4j:zip4j:2.7.0') , mailJavax('javax.mail:mail:1.4.7') , mailSun('com.sun.mail:javax.mail:1.6.0') , mailCommons('org.apache.commons:commons-email:1.5') , mailVertx('io.vertx:vertx-mail-client:3.5.2') - , httpWinSupport('org.apache.httpcomponents:httpclient-win:4.5.6') - , httpCore('org.apache.httpcomponents:httpcore:4.4.10') - , httpClient("org.apache.httpcomponents:httpclient:4.5.6") + , httpWinSupport('org.apache.httpcomponents:httpclient-win:4.5.13') + , httpCore('org.apache.httpcomponents:httpcore:4.4.13') + , httpCoreNio('org.apache.httpcomponents:httpcore-nio:4.4.13') + , httpClient("org.apache.httpcomponents:httpclient:4.5.13") , commonsHttpOld('commons-httpclient:commons-httpclient:3.1') , portForward('net.kanstren.tcptunnel:tcptunnel:1.1.2') - // jediterm failed if higher version of guava + // old jediterm failed if higher version of guava , guavaMavenId('com.google.guava:guava:21.0') , guavaMavenIdNew('com.google.guava:guava:26.0-jre') , xmlApisExt('xml-apis:xml-apis-ext:1.3.04') , xercesImpl('xerces:xercesImpl:2.11.0') , jfreeCommon('org.jfree:jcommon:1.0.24') , yandexDisk('com.yandex.android:disk-restapi-sdk:1.03') - , jfreeChart('org.jfree:jfreechart:1.5.0') - , rhino('org.mozilla:rhino:1.7.10') - , commnonsLang3('org.apache.commons:commons-lang3:3.8.1') + , jfreeChart('org.jfree:jfreechart:1.5.3') + , rhino('org.mozilla:rhino:1.7.13') + , commnonsLang3('org.apache.commons:commons-lang3:3.12.0') , commonsCollection('commons-collections:commons-collections:3.2.2') - , commonsCodec('commons-codec:commons-codec:1.11') + , commonsCodec('commons-codec:commons-codec:1.15') , servletApi('org.apache.tomcat:servlet-api:6.0.53') // visual diff and merge tool , jmeld('org.devocative:jmeld:3.2') , javaRepl('com.javarepl:javarepl:431') - , groovySshShell('me.bazhenov.groovy-shell:groovy-shell-server:2.0.0') , dropbox('com.dropbox.core:dropbox-core-sdk:3.0.10') - , javaCompiler1('com.github.javaparser:javaparser-core:3.6.26') - , javaCompiler2Janino('org.codehaus.janino:janino:3.0.10') - , webDavClient('com.github.lookfirst:sardine:5.8') + , javaCompiler1('com.github.javaparser:javaparser-core:3.20.0') + , javaCompiler2Janino('org.codehaus.janino:janino:3.1.0') + , javaCompilerJaninoCommon('org.codehaus.janino:commons-compiler:3.1.0') + , webDavClient('com.github.lookfirst:sardine:5.9') , eclipseGroovyBatchCompiler('org.codehaus.groovy:groovy-eclipse-batch:2.4.13-01') , icePdfCore('org.icepdf.os:icepdf-core:6.2.2') , icePdfViewer('org.icepdf.os:icepdf-viewer:6.2.2') // comparision : http://ssh-comparison.quendi.de/comparison/cipher.html , j2sshMaverick('com.sshtools:j2ssh-maverick:1.5.5') + , sshjHierynomus('com.hierynomus:sshj:0.31.0') + , + // not much doc + trileadSsh('com.trilead:trilead-ssh2:1.0.0-build222') + , + // higher version depends on groovy 3 + groovySshShell('me.bazhenov.groovy-shell:groovy-shell-server:2.0.3') , commonsNet('commons-net:commons-net:3.6') , commonsCollection4('org.apache.commons:commons-collections4:4.2') , jansi('org.fusesource.jansi:jansi:1.17.1') - , jsoup('org.jsoup:jsoup:1.11.3') - , jcraft('com.jcraft:jsch:0.1.54') + , jsoup('org.jsoup:jsoup:1.12.1') + /** + * @see net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences#jschDocumentationBinWithSrc + */ + , jcraft('com.jcraft:jsch:0.1.55') , jcraftZlib('com.jcraft:jzlib:1.1.3') , jideOss('com.jidesoft:jide-oss:3.6.18') , jmdns('javax.jmdns:jmdns:3.4.1') , jcifs('jcifs:jcifs:1.3.17') , commonsCli('commons-cli:commons-cli:1.4') , commonsConfig('commons-configuration:commons-configuration:1.10') - , asmOw2All('org.ow2.asm:asm-all:5.2') , jetbrainsAnnotations('org.jetbrains:annotations-java5:16.0.3') , mx4j('mx4j:mx4j-tools:3.0.1') - , trileadSsh('com.trilead:trilead-ssh2:1.0.0-build221') , cssParser('org.w3c.css:sac:1.3') , cssParser2('net.sf.cssbox:jstyleparser:3.2') - , cssParser3('net.sourceforge.cssparser:cssparser:0.9.26') - , commonsCompress('org.apache.commons:commons-compress:1.18') + , cssParser3('net.sourceforge.cssparser:cssparser:0.9.29') + , commonsCompress('org.apache.commons:commons-compress:1.20') , pureJavaComm('com.github.purejavacomm:purejavacomm:1.0.2.RELEASE') , networkTestFramework('com.github.netcrusherorg:netcrusher-core:0.10') , kryoSerializer('com.esotericsoftware:kryo-shaded:4.0.2') @@ -118,17 +128,64 @@ enum LatestMavenIds implements MavenIdContains { , commonsIo(CustObjMavenIds.commonsIo) // http://repo1.maven.org/maven2/org/apache/commons/commons-io/1.3.2/commons-io-1.3.2.pom , commonsIoBad('org.apache.commons:commons-io:1.3.2') - , jasperreports('net.sf.jasperreports:jasperreports:6.7.0') + , jasperreports('net.sf.jasperreports:jasperreports:6.16.0') , quartz('org.quartz-scheduler:quartz:2.3.0') - , winKillProcessTree('org.jvnet.winp:winp:1.27') + , winKillProcessTree('org.jvnet.winp:winp:1.28') , hamcrest('org.hamcrest:java-hamcrest:2.0.0.0') , svnKit(CustObjMavenIds.svnKit) + , groovyCodeAnalizer('org.codenarc:CodeNarc:1.5') + , trove4jIdea('org.jetbrains.intellij.deps:trove4j:1.0.20200330') + , + // add lz4Compressor to classpath + svnCli('org.tmatesoft.svnkit:svnkit-cli:1.10.3') , fernflowerJavaDecompiler('org.jboss.windup.decompiler.fernflower:windup-fernflower:1.0.0.20171018') - , fernflowerLogger('org.jboss.windup.decompiler:decompiler-fernflower:4.0.1.Final') + , fernflowerLogger('org.jboss.windup.decompiler:decompiler-fernflower:5.1.3.Final') + , fernflowerJavaDecompilerApi('org.jboss.windup.decompiler:decompiler-api:5.1.3.Final') + , cfrJavaDecompilerApi('org.benf:cfr:0.151') , fontChooser('io.github.dheid:fontchooser:2.3') - , opencsv("com.opencsv:opencsv:4.3.2") + , opencsv("com.opencsv:opencsv:5.5.1") + , powerShellWrapper('com.github.tuupertunut:powershell-lib-java:2.0.0' ) +// , kotlinStd("org.jetbrains.kotlin:kotlin-stdlib:1.3.31") // , jasypt('org.jasypt:jasypt:1.9.2') - , eclipseGitHubApi('org.eclipse.mylyn.github:org.eclipse.egit.github.core:5.0.0.201806131550-r') + + , + eclipseGitHubApi(MavenIdAndRepoCustom.eclipseGitHubApi.m) + , python('org.python:jython-standalone:2.7.2') + , args4j('args4j:args4j:2.33') + , quickfixj('org.quickfixj:quickfixj-all:2.1.1') + , minaCore('org.apache.mina:mina-core:2.1.3') + , javaApiCompare('com.github.siom79.japicmp:japicmp:0.15.3') + , jcabiGithub('com.jcabi:jcabi-github:1.1.2') + , lz4Compressor('org.lz4:lz4-java:1.7.1') + , + // maven launcher + plexusClassworlds('org.codehaus.plexus:plexus-classworlds:2.6.0') + ,maven_resolver_provider('org.apache.maven:maven-resolver-provider:3.8.1') + ,plexus_utils('org.codehaus.plexus:plexus-utils:3.3.0'), + + // Class org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest + annotationHell('org.springframework.boot:spring-boot-test-autoconfigure:2.2.0.RELEASE') + , + dockerJibCore('com.google.cloud.tools:jib-core:0.18.0') + , + dockerJava('com.github.docker-java:docker-java:3.2.8'), + heapAnalizerUi('org.netbeans.modules:org-netbeans-modules-profiler-heapwalker:RELEASE121'), + // com.intellij.diagnostic.hprof.Analyzer + heapAnalizerCore('org.netbeans.modules:org-netbeans-lib-profiler:RELEASE121'), + // org.eclipse.mat.snapshot.SnapshotFactory + heapAnalizerMat('com.github.cormoran-io.pepper:pepper-mat:2.0'), + primitiveCollections('it.unimi.dsi:fastutil:8.5.2'), + // TODO add connection killer + oracleJdbc('com.oracle.database.jdbc.debug:ojdbc8_g:21.1.0.0'), + zxingCore('com.google.zxing:core:3.4.1'), + //below 3 svn stiff needed only for compile + svnNativeClintWrapper('org.tmatesoft.svnkit:svnkit-javahl16:1.10.3'), + svnClientAdapterJavahlUseless( 'org.netbeans.external:svnClientAdapter-javahl:RELEASE123'), + svnClientAdapterMainUseless( 'org.netbeans.external:svnClientAdapter-main:RELEASE123'), + +// org.apache.httpcomponents:httpcore:4.4.10 see in DropshipClasspath + // xmlApis('xml-apis:xml-apis:1.4.01') see in DropshipClasspath + // antlrRuntime('org.antlr:antlr-runtime:3.5.2') in CustObjMavenIds ; @@ -143,13 +200,19 @@ enum LatestMavenIds implements MavenIdContains { this.m = m.getM() } + + @Override + File resolveToFile() { + return m.resolveToFile() + } + static MavenCommonUtils mcu = new MavenCommonUtils() - public static List jol = [ - new MavenId('org.openjdk.jol:jol-samples:0.9'), - new MavenId('org.openjdk.jol:jol-cli:0.9'), - new MavenId('org.openjdk.jol:jol-core:0.9'), - ] +// public static List jol = [ +// new MavenId('org.openjdk.jol:jol-samples:0.9'), +// new MavenId('org.openjdk.jol:jol-cli:0.9'), +// new MavenId('org.openjdk.jol:jol-core:0.9'), +// ] // 'com.google.http-client:google-http-client:1.21.0'), // 'com.google.oauth-client:google-oauth-client:1.21.0'), @@ -159,11 +222,17 @@ enum LatestMavenIds implements MavenIdContains { public - static List specific = [CustObjMavenIds.git, junit, CustObjMavenIds.slf4jApi, jnrJffi, portForward, jna, jnaPlatform, gnuGetOpt, jodaTime, rstaui, eclipseJavaCompiler, eclipseJavaAstParser,rsyntaxtextarea, jfreeCommon, jfreeChart, CustObjMavenIds.commnonsLang, commonsCollection, commnonsLang3, commonsCodec, groovySshShell, javaCompiler1, icePdfCore, icePdfViewer, j2sshMaverick, commonsNet, commonsCollection4, jansi, jsoup, jcraft, httpClient, httpCore, jideOss, jmdns, jcifs, mx4j, trileadSsh, cssParser, commonsHttpOld, cssParser3, asmOw2All, compressAbstraction, commonsCompress, jasperreports, quartz, winKillProcessTree, svnKit, fernflowerJavaDecompiler, fernflowerLogger, fontChooser, opencsv,] + static List specific = [GitMavenIds.jgit, junit, CustObjMavenIds.slf4jApi, jnrJffi, portForward, jna, jnaPlatform, gnuGetOpt, jodaTime, rstaui,// + CustObjMavenIds.eclipseJavaCompiler, CustObjMavenIds.eclipseJavaAstParser, rsyntaxtextarea, jfreeCommon, jfreeChart, CustObjMavenIds.commnonsLang, commonsCollection,// + commnonsLang3, commonsCodec, groovySshShell, javaCompiler1, icePdfCore, icePdfViewer, j2sshMaverick, commonsNet, commonsCollection4,// + jansi, jsoup, jcraft, httpClient, httpCore,httpCoreNio, jideOss, jmdns, jcifs, mx4j, trileadSsh, cssParser, commonsHttpOld, cssParser3, CustObjMavenIds.compressAbstraction,// + commonsCompress, jasperreports, quartz, winKillProcessTree, svnKit, fernflowerJavaDecompiler, fernflowerLogger, fontChooser, opencsv,svnCli, + powerShellWrapper,zxingCore, + ] public - static List usefulMavenIdSafeToUseLatest = DropshipClasspath.allLibsWithoutGroovy + loggingPrefix + (List) AntMavenIds.all +(List) SshdMavenIds.all + (List) Log4j2MavenIds.all + (List) specific + (List) CustObjMavenIds.all + static List usefulMavenIdSafeToUseLatest = DropshipClasspath.allLibsWithoutGroovy + loggingPrefix + (List) AntMavenIds.all + (List) Log4j2MavenIds.all + (List) specific + (List) CustObjMavenIds.all static MavenIdContains filterOnMavenId(MavenId mavenId) { @@ -182,7 +251,7 @@ enum LatestMavenIds implements MavenIdContains { case { artifact == 'google-collections' }: return null case { artifact == 'commons-logging-api' }: - return commonsLoggingMavenId + return CustObjMavenIds.commonsLoggingMavenId case { mavenId.isGroupAndArtifact(jline2) }: return jline2 case { mavenId.isGroupAndArtifact(xmlApiId) }: @@ -200,5 +269,4 @@ enum LatestMavenIds implements MavenIdContains { } } - } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Log4j2MavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Log4j2MavenIds.groovy index 89f65730..a37cc94f 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Log4j2MavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Log4j2MavenIds.groovy @@ -4,11 +4,13 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider import java.util.logging.Logger @CompileStatic -enum Log4j2MavenIds implements MavenIdContains { +enum Log4j2MavenIds implements MavenIdContains , EnumNameProvider, ToFileRef2{ api, @@ -24,10 +26,19 @@ enum Log4j2MavenIds implements MavenIdContains { Log4j2MavenIds() { String artifactId = name().replace('_', '-') - m = new MavenId("org.apache.logging.log4j:log4j-${artifactId}:2.11.1"); + m = new MavenId("org.apache.logging.log4j:log4j-${artifactId}:2.14.1"); } public static List all = (List) values().toList() + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MaryDependentMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MaryDependentMavenIds.groovy new file mode 100644 index 00000000..2c1e5df2 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MaryDependentMavenIds.groovy @@ -0,0 +1,24 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains; + +import java.util.logging.Logger; + +@CompileStatic +enum MaryDependentMavenIds implements MavenIdContains{ + + jwordnet('net.sf.jwordnet:jwnl:1.3.3'), + math_jama('gov.nist.math:jama:1.0.3'), + opennlp_maxent('org.apache.opennlp:opennlp-maxent:3.0.3'), + opennlp_tools('org.apache.opennlp:opennlp-tools:1.5.3'), + ; + + MavenId m; + + MaryDependentMavenIds(String m) { + this.m = new MavenId(m) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MaryTtsMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MaryTtsMavenIds.groovy new file mode 100644 index 00000000..ff7bcab7 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MaryTtsMavenIds.groovy @@ -0,0 +1,40 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepo +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepoContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.MavenRepositoriesEnum + +@CompileStatic +enum MaryTtsMavenIds implements MavenIdAndRepoContains, ToFileRef2 { + + fast_md5('com.twmacinta:fast-md5:2.7.1'), + emotionml_checker('de.dfki.mary:emotionml-checker-java:1.1'), + voice_cmu_slt_hsmm('de.dfki.mary:voice-cmu-slt-hsmm:5.2'), + marytts_common('de.dfki.mary:marytts-common:5.2'), + marytts_runtime('de.dfki.mary:marytts-runtime:5.2'), + marytts_lang_en('de.dfki.mary:marytts-lang-en:5.2'), + marytts_lang_ru('de.dfki.mary:marytts-lang-ru:5.2'), + marytts_signalproc('de.dfki.mary:marytts-signalproc:5.2'), + jtok_core('de.dfki.lt.jtok:jtok-core:1.9.3'), + mathJampack('gov.nist.math:Jampack:1.0'), + ; + + + MavenIdAndRepo mavenIdAndRepo; + + + MaryTtsMavenIds(String m2) { + this.mavenIdAndRepo = new MavenIdAndRepo(new MavenId(m2), MavenRepositoriesEnum.jcenter) + } + + + @Override + File resolveToFile() { + return mavenIdAndRepo.resolveToFile() + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenIdAndRepoCustom.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenIdAndRepoCustom.groovy new file mode 100644 index 00000000..3cac9d80 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenIdAndRepoCustom.groovy @@ -0,0 +1,36 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepo +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepoContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.mdep.ivy.IBiblioRepository +import net.sf.jremoterun.utilities.nonjdk.classpath.MavenRepositoriesEnum; + +import java.util.logging.Logger; + +@CompileStatic +enum MavenIdAndRepoCustom implements MavenIdAndRepoContains, ToFileRef2{ + eclipseGitHubApi(new MavenId('org.eclipse.mylyn.github:org.eclipse.egit.github.core:5.7.0.202003110725-r'), MavenRepositoriesEnum.eclipse), + ; + + MavenId m; + IBiblioRepository repo; + + MavenIdAndRepoCustom(MavenId m, IBiblioRepository repo) { + this.m = m + this.repo = repo + } + + @Override + MavenIdAndRepo getMavenIdAndRepo() { + return new MavenIdAndRepo(m,repo) + } + + @Override + File resolveToFile() { + return getMavenIdAndRepo().resolveToFile() + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenMavenIdRandom.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenMavenIdRandom.groovy new file mode 100644 index 00000000..51b4ec0d --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenMavenIdRandom.groovy @@ -0,0 +1,40 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +@CompileStatic +enum MavenMavenIdRandom implements MavenIdContains, EnumNameProvider, ToFileRef2 { + + sharedUtils('org.apache.maven.shared:maven-shared-utils:3.2.1'), + wagonProviderApi('org.apache.maven.wagon:wagon-provider-api:3.3.3'), + ; + + + MavenId m; + + MavenMavenIdRandom(String m2) { + this.m = new MavenId(m2) + } + + MavenMavenIdRandom(MavenIdContains m) { + this.m = m.getM() + } + + public static List all = values().toList() + + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenMavenIds.groovy new file mode 100644 index 00000000..cf8f2e21 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenMavenIds.groovy @@ -0,0 +1,49 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +@CompileStatic +enum MavenMavenIds implements MavenIdContains, EnumNameProvider, ToFileRef2 { + + artifact, + builder_support, + compat, + core, + embedder, + model, + model_builder, + plugin_api, + repository_metadata, + resolver_provider, + settings, + settings_builder, + slf4j_provider, + ; + + + MavenId m; + + MavenMavenIds() { + String artifactId = 'maven-'+name().replace('_', '-') + m = new MavenId('org.apache.maven', artifactId, '3.6.2'); + } + + public static List all = values().toList() + + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenResolverMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenResolverMavenIds.groovy new file mode 100644 index 00000000..d87fb6e3 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MavenResolverMavenIds.groovy @@ -0,0 +1,45 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +@CompileStatic +enum MavenResolverMavenIds implements MavenIdContains, EnumNameProvider, ToFileRef2 { + + api, + connector_basic, + impl, + named_locks, + spi, + transport_http, + transport_wagon, + util, + ; + + + MavenId m; + + MavenResolverMavenIds() { + String artifactId = 'maven-resolver-' + name() + artifactId = artifactId.replace('_', '-') + m = new MavenId('org.apache.maven.resolver', artifactId, '1.7.0'); + } + + public static List all = values().toList() + + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MigLayoutMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MigLayoutMavenIds.groovy index 74618542..3dd508b0 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MigLayoutMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/MigLayoutMavenIds.groovy @@ -3,14 +3,16 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs; import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains -import net.sf.jremoterun.utilities.mdep.DropshipClasspath; +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider; import java.util.logging.Logger; import groovy.transform.CompileStatic; @CompileStatic -enum MigLayoutMavenIds implements MavenIdContains{ +enum MigLayoutMavenIds implements MavenIdContains, EnumNameProvider, ToFileRef2{ examples, demo, @@ -26,12 +28,20 @@ enum MigLayoutMavenIds implements MavenIdContains{ //'org.codehaus.groovy:groovy_console:2.4.13' MigLayoutMavenIds() { // String artifactId = name() - m = new MavenId("com.miglayout", 'miglayout-' + name(), '5.1'); + m = new MavenId("com.miglayout", 'miglayout-' + name(), '5.2'); } public static List all = (List) values().toList() + @Override + String getCustomName() { + return m.artifactId + } + @Override + File resolveToFile() { + return m.resolveToFile() + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/NettyMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/NettyMavenIds.groovy new file mode 100644 index 00000000..82e755f2 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/NettyMavenIds.groovy @@ -0,0 +1,68 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +@CompileStatic +enum NettyMavenIds implements MavenIdContains , EnumNameProvider, ToFileRef2{ + + + transport_native_unix_common, + transport_native_kqueue, + microbench, + testsuite_http2, + testsuite_autobahn, + transport_native_unix_common_tests, + codec_smtp, + codec_redis, + dev_tools, + all, + transport_native_epoll, + testsuite_osgi, + testsuite, + example, + handler_proxy, + transport_udt, + transport_sctp, + transport_rxtx, + resolver_dns, + codec_xml, + codec_stomp, + codec_socks, + codec_mqtt, + codec_memcache, + codec_http2, + codec_http, + handler, + codec_haproxy, + codec_dns, + codec, + transport, + resolver, + buffer, + common + ; + + + MavenId m; + + NettyMavenIds() { + m = new MavenId('io.netty','netty-'+ name().replace('_', '-'), '4.1.31.Final'); + } + + public static List allEnums = values().toList() + + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/NexusSearchMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/NexusSearchMavenIds.groovy index 95dc2b96..734ed400 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/NexusSearchMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/NexusSearchMavenIds.groovy @@ -3,15 +3,16 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 @CompileStatic -enum NexusSearchMavenIds implements MavenIdContains { +enum NexusSearchMavenIds implements MavenIdContains, ToFileRef2 { - indexer('org.sonatype.nexus.plugins:nexus-indexer-lucene-model:2.14.9-01'), - restletBridge('org.sonatype.nexus.plugins:nexus-restlet-bridge:2.14.9-01'), - rest('org.sonatype.nexus:nexus-rest:3.12.1-01'), - restlet1x('org.sonatype.nexus.plugins:nexus-restlet1x-model:2.14.9-01'), - xstream('com.thoughtworks.xstream:xstream:1.4.10'), + indexer('org.sonatype.nexus.plugins:nexus-indexer-lucene-model:2.14.20-01'), + restletBridge('org.sonatype.nexus.plugins:nexus-restlet-bridge:2.14.20-01'), + rest('org.sonatype.nexus:nexus-rest:3.30.0-01'), + restlet1x('org.sonatype.nexus.plugins:nexus-restlet1x-model:2.14.20-01'), + xstream('com.thoughtworks.xstream:xstream:1.4.16'), xpp3XmlParser('xpp3:xpp3:1.1.4c'), ; @@ -26,5 +27,8 @@ enum NexusSearchMavenIds implements MavenIdContains { public static List all = (List) values().toList() - + @Override + File resolveToFile() { + return m.resolveToFile() + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Okhttp3MavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Okhttp3MavenIds.groovy new file mode 100644 index 00000000..2564f799 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Okhttp3MavenIds.groovy @@ -0,0 +1,41 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +@CompileStatic +enum Okhttp3MavenIds implements MavenIdContains, ToFileRef2, EnumNameProvider { + + okhttp_urlconnection, + okhttp_tls, + okhttp_sse, + logging_interceptor, + okhttp_dnsoverhttps, + okhttp_brotli, + okhttp, + okcurl, + ; + + MavenId m; + + Okhttp3MavenIds() { + String artifactId = name().replace('_', '-') + m = new MavenId("com.squareup.okhttp3:${artifactId}:4.9.1"); + } + + public static List all = (List) values().toList() + + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Pi4j.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Pi4j.groovy new file mode 100644 index 00000000..516967bc --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/Pi4j.groovy @@ -0,0 +1,36 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +@CompileStatic +enum Pi4j implements MavenIdContains, ToFileRef2, EnumNameProvider { + pi4j_example, + pi4j_device, + pi4j_gpio_extension, + pi4j_core, + ; + + + MavenId m; + + Pi4j() { + m = new MavenId('com.pi4j', name().replace('_','-'), '1.3'); + } + + public static List all = values().toList() + + @Override + File resolveToFile() { + return m.resolveToFile() + } + + @Override + String getCustomName() { + return m.artifactId; + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/ProguardMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/ProguardMavenIds.groovy index 2b3e76e4..4fbcf4f2 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/ProguardMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/ProguardMavenIds.groovy @@ -3,10 +3,12 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider @CompileStatic -enum ProguardMavenIds implements MavenIdContains{ +enum ProguardMavenIds implements MavenIdContains, EnumNameProvider, ToFileRef2{ base, gradle, @@ -19,9 +21,20 @@ enum ProguardMavenIds implements MavenIdContains{ ProguardMavenIds() { String artifactId = name() - m = new MavenId("net.sf.proguard:proguard-${artifactId}:5.3.3"); + m = new MavenId("net.sf.proguard:proguard-${artifactId}:6.2.2"); } public static List all = (List) values().toList() + + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } } \ No newline at end of file diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SquirrelSqlMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SquirrelSqlMavenIds.groovy index 6cc5f947..290fa819 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SquirrelSqlMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SquirrelSqlMavenIds.groovy @@ -2,14 +2,16 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs; import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenId -import net.sf.jremoterun.utilities.classpath.MavenIdContains; +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider; import java.util.logging.Logger; import groovy.transform.CompileStatic; @CompileStatic -enum SquirrelSqlMavenIds implements MavenIdContains { +enum SquirrelSqlMavenIds implements MavenIdContains, EnumNameProvider, ToFileRef2 { @@ -31,4 +33,13 @@ enum SquirrelSqlMavenIds implements MavenIdContains { public static List all = (List) values().toList() + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SshdMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SshdMavenIds.groovy index fa4e2720..fe25c3a8 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SshdMavenIds.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SshdMavenIds.groovy @@ -2,13 +2,16 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs import groovy.transform.CompileStatic; import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.classpath.MavenId -import net.sf.jremoterun.utilities.classpath.MavenIdContains; +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider; import java.util.logging.Logger; @CompileStatic -enum SshdMavenIds implements MavenIdContains { +enum SshdMavenIds implements MavenIdContains , EnumNameProvider, ToFileRef2{ cli, spring_sftp, @@ -20,6 +23,7 @@ enum SshdMavenIds implements MavenIdContains { netty, mina, core, + //openpgp, putty, common, // apache_sshd, @@ -31,10 +35,23 @@ enum SshdMavenIds implements MavenIdContains { SshdMavenIds() { String artifact = 'sshd-' + name().replace('_','-') + // only 2.1.0 compatible with groovySsh : 2.2.0 not + //new ClRef('me.bazhenov.groovysh.GroovyShellService'); m = new MavenId("org.apache.sshd", artifact, '2.1.0'); + } public static List all = (List) values().toList() + + @Override + String getCustomName() { + return m.artifactId + } + + @Override + File resolveToFile() { + return m.resolveToFile() + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SvnRefs.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SvnRefs.groovy index 2cde74a6..2e087c76 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SvnRefs.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/SvnRefs.groovy @@ -1,7 +1,6 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.refs; import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.nonjdk.git.SvnRef import net.sf.jremoterun.utilities.nonjdk.git.SvnSpec; import java.util.logging.Logger; diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/TwelvemonkeysImageioMavenIds.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/TwelvemonkeysImageioMavenIds.groovy new file mode 100644 index 00000000..2aec6ae4 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/refs/TwelvemonkeysImageioMavenIds.groovy @@ -0,0 +1,56 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider; + +import java.util.logging.Logger; + +@CompileStatic +enum TwelvemonkeysImageioMavenIds implements MavenIdContains, ToFileRef2, EnumNameProvider { + + batik, + bmp, + clippath, + core, + hdr, + icns, + iff, + jpeg, + metadata, + pcx, + pdf, + pict, + pnm, + psd, + reference, + sgi, + tga, + thumbsdb, + tiff, +; + + MavenId m; + + TwelvemonkeysImageioMavenIds() { + String artifactId = 'imageio-'+name() + m = new MavenId('com.twelvemonkeys.imageio', artifactId, '3.4.2'); + } + + public static List all = values().toList() + + @Override + File resolveToFile() { + return m.resolveToFile() + } + + @Override + String getCustomName() { + return m.artifactId; + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/repohash/GrapeRepoHashToFileMap.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/repohash/GrapeRepoHashToFileMap.groovy index 9ebf018c..140fc850 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/repohash/GrapeRepoHashToFileMap.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/repohash/GrapeRepoHashToFileMap.groovy @@ -6,6 +6,9 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenCommonUtils import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.BaseDirSetting +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import net.sf.jremoterun.utilities.nonjdk.ideadep.LongTaskInfo import org.apache.commons.codec.digest.DigestUtils @@ -25,14 +28,14 @@ class GrapeRepoHashToFileMap { public - static File noMavenIdFilesJsonDefault = new File(MavenDefaultSettings.mavenDefaultSettings.userHome, "jrr/configs/ivy_hash_cache2.json") + static ToFileRef2 noMavenIdFilesJsonDefault = BaseDirSetting.baseDirSetting.childL("configs/ivy_hash_cache2.json") void init(LongTaskInfo longTaskInfo) { Date start = new Date() Map fileCache3 = [:] - fileCache3.putAll(File2HashMapJsonSaver.readJson2(noMavenIdFilesJsonDefault)) + fileCache3.putAll(File2HashMapJsonSaver.readJson2(noMavenIdFilesJsonDefault.resolveToFile())) mavenCommonUtils.mavenDefaultSettings.grapeLocalDir.eachFileRecurse(FileType.FILES, { @@ -71,7 +74,7 @@ class GrapeRepoHashToFileMap { } }) initTime = System.currentTimeMillis() - start.time - File2HashMapJsonSaver.saveToJson(fileCache3, noMavenIdFilesJsonDefault) + File2HashMapJsonSaver.saveToJson(fileCache3, noMavenIdFilesJsonDefault.resolveToFile()) } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/repohash/MavenRepoHashToFileMap.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/repohash/MavenRepoHashToFileMap.groovy index c3196b7c..e2d8f8c2 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/repohash/MavenRepoHashToFileMap.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/repohash/MavenRepoHashToFileMap.groovy @@ -24,6 +24,9 @@ class MavenRepoHashToFileMap { void init(LongTaskInfo longTaskInfo){ + if(longTaskInfo==null){ + throw new NullPointerException('longTaskInfo is null') + } Date start = new Date() diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/BintraySearch.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/BintraySearch.groovy new file mode 100644 index 00000000..b05c03b6 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/BintraySearch.groovy @@ -0,0 +1,73 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.search + +import groovy.json.JsonSlurper +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.nonjdk.classpath.UserBintrayRepo +import net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers.ClassPathCalculatorGroovyWithDownloadWise; + +import java.util.logging.Logger; + +@CompileStatic +class BintraySearch { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + boolean ignoreBadPath = true; + + + String urlPrefix = 'https://api.bintray.com/search/file?sha1=' + + List searchBySha1(File file) { + String hash = ClassPathCalculatorGroovyWithDownloadWise.calcSha1ForFile(file); + return searchBySha1(hash) + } + + List searchBySha1(String sha1) { + URL u = new URL(urlPrefix + sha1) + return parseReply(u.text); + + } + + List parseReply(String text) { + try { + List parse = new JsonSlurper().parseText(text) as List + return parse.collect { parseElement((Map) it) }.findAll { it != null } + } catch (Exception e) { + throw new Exception("Failed parse : ${text}", e) + } + } + + String getEl(Map allEls, String elName) { + String elResult = allEls.get(elName) + if (elResult == null) { + throw new Exception("${elName} not found : ${allEls}") + } + return elResult + } + + BintraySearchResult parseElement(Map el) { + BintraySearchResult bintraySearchResult = new BintraySearchResult() + String repo1 = getEl(el, 'repo'); + String owner1 = getEl(el, 'owner'); + String path1 = getEl(el, 'path'); + bintraySearchResult.bintrayRepo = new UserBintrayRepo(owner1 + '/' + repo1); + //org/jetbrains/intellij/deps/completion/ranking/java/0.0.3/java-0.0.3.jar + List pathTokenize = path1.tokenize('/') + if (pathTokenize.size() < 3) { + if (ignoreBadPath) { + log.info "bad path : ${pathTokenize} from ${el}" + return null + } + throw new Exception("bad path : ${pathTokenize}") + } + pathTokenize.remove(pathTokenize.size() - 1) + String version1 = pathTokenize.remove(pathTokenize.size() - 1) + String artifact1 = pathTokenize.remove(pathTokenize.size() - 1) + String groupId1 = pathTokenize.join('.') + bintraySearchResult.mavenId = new MavenId(groupId1, artifact1, version1) + bintraySearchResult.rawResult = el; + return bintraySearchResult; + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/BintraySearchResult.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/BintraySearchResult.groovy new file mode 100644 index 00000000..0e7b2b33 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/BintraySearchResult.groovy @@ -0,0 +1,23 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.search + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.nonjdk.classpath.UserBintrayRepo; + +import java.util.logging.Logger; + +@CompileStatic +class BintraySearchResult { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public UserBintrayRepo bintrayRepo; + + public MavenId mavenId; + public Map rawResult; + + @Override + String toString() { + return mavenId.toString() + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/FindMavenIdsAndDownload.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/FindMavenIdsAndDownload.groovy index 043f41cf..adddfaf0 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/FindMavenIdsAndDownload.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/FindMavenIdsAndDownload.groovy @@ -1,18 +1,14 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.search -import groovy.json.JsonSlurper + import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings -import net.sf.jremoterun.utilities.classpath.MavenDependenciesResolver import net.sf.jremoterun.utilities.classpath.MavenId -import net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers.ClassPathCalculatorGroovyWise +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepo import net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers.ClassPathCalculatorGroovyWithDownloadWise -import net.sf.jremoterun.utilities.nonjdk.classpath.search.MavenSearch import net.sf.jremoterun.utilities.nonjdk.ideadep.InternetAccess import net.sf.jremoterun.utilities.nonjdk.ideadep.LongTaskInfo -import org.joda.time.Period import java.util.logging.Level import java.util.logging.Logger @@ -27,6 +23,8 @@ class FindMavenIdsAndDownload implements InternetAccess { int retryCount = 2 + public static MavenSearch mavenSearch = new MavenSearch() + MavenId findMavenIdsAndDownload4(File it, LongTaskInfo longTaskInfo) { String hash = ClassPathCalculatorGroovyWithDownloadWise.calcSha1ForFile(it); @@ -39,14 +37,18 @@ class FindMavenIdsAndDownload implements InternetAccess { MavenId findMavenIdsAndDownload3(File file, String hex, LongTaskInfo longTaskInfo) { longTaskInfo.startSubTask("Resolving maven id ${file}") - MavenId mavenId = findMavenIdsAndDownload5(file, hex) + MavenId mavenId = findMavenIdsAndDownloadCentral(file, hex) longTaskInfo.finishSubTask() return mavenId } - MavenId findMavenIdsAndDownload5(File file, String hex) { + MavenIdAndRepo findMavenIdsAndDownloadBintray(File file, String hex) { + + } + + MavenId findMavenIdsAndDownloadCentral(File file, String hex) { try { - List response = MavenSearch.findMavenIdsAndDownload6(file, hex) + List response = mavenSearch.findMavenIdsAndDownload6(file, hex) switch (response.size()) { case 0: log.info "not found for ${file.absolutePath}" diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenElementsGet.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenElementsGet.groovy new file mode 100644 index 00000000..4d839eef --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenElementsGet.groovy @@ -0,0 +1,122 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.search + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenVersionComparator +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import org.jsoup.nodes.Node +import org.jsoup.nodes.TextNode +import org.jsoup.select.Elements; + +import java.util.logging.Logger; + +@CompileStatic +class MavenElementsGet { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + List getElements(URL url, boolean needFiles) { + long startTime = System.currentTimeMillis() + Document doc = Jsoup.connect(url.toString()).get(); + long duration = System.currentTimeMillis() - startTime + checkDuration(url, duration) + Elements newsHeadlines = doc.select("a"); + if (newsHeadlines.size() == 0) { + throw new Exception("a elements not found on ${url}") + } + List collect1 = newsHeadlines.collect { getRef(it,needFiles) } + collect1 = collect1.findAll { it != null } + if (collect1.size() == 0) { + throw new Exception("No good a elements found on ${url}") + } + return collect1; + } + + Map findLatestVersionForArtifacts(URL url) { + String parentUrl = url.toString() + if (!parentUrl.endsWith('/')) { + parentUrl += '/' + } + Map result = [:] + List elements = getElements(url,false) + elements.each { + URL url12 = new URL(parentUrl + it + '/'); + String latestVer = findLatestVersionForArtifact(url12); + result.put(it, latestVer); + } + return result + } + + void checkDuration(URL url, long duration) { + if (duration > 5000) { + log.info "long duration ${duration / 1000} sec for ${url}" + } + } + + + String findLatestVersionForArtifact(URL url) { + List elements = getElements(url,false) + return findLatestVersionFromList(elements) + } + + String getRef(Element element, boolean needFiles) { + List nodes = element.childNodes() + if (nodes.size() != 1) { + return null + } + Node node = nodes.get(0) + if (!(node instanceof TextNode)) { + return false + } + TextNode tn = (TextNode) node; + String text1 = tn.text() + final String textOrig = text1 + text1 = text1.trim() + boolean needed = isTextNeedInclude(tn, text1, needFiles) + if (!needed) { + return null + } + if (text1.endsWith('/')) { + text1 = text1.substring(0, text1.length() - 1) + } + boolean isGood = isTextGood(text1) + if (!isGood) { + throw new Exception("Bad text : ${textOrig}") + } + return text1 + } + + boolean isTextNeedInclude(TextNode tn, String text, boolean needFiles) { + if (text.contains('Parent directory')) { + return false + } + if (text.contains('..')) { + return false + } + if (needFiles) { + return !text.endsWith('/') + } + return text.endsWith('/') + } + + boolean isTextGood(String text1) { + boolean isBad = text1.contains('/') || text1.contains(' ') || text1.contains('\n') || text1.contains('"') || text1.contains("'") + return !isBad + } + + + String findLatestVersionFromList(List els) { + MavenVersionComparator comparator = new MavenVersionComparator() + String ver = els.first() + els.each { + int res = comparator.isOverrideMavenId(ver, it) + if (res > 0) { + ver = it + } + } + return ver + + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenResponseParser.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenResponseParser.groovy index 1905b6b7..503a1b49 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenResponseParser.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenResponseParser.groovy @@ -1,30 +1,80 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.search +import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.MavenId import java.util.logging.Logger +//@CompileStatic class MavenResponseParser { - private static final Logger log = Logger.getLogger(MavenResponseParser.name); + private static final Logger log = Logger.getLogger(MavenResponseParser.getName()); - static List parseResponse(Object json){ + public Date acceptOnlyAfterDate; + + static List parseResponse(Map json) { try { return json.response.docs.collect { it.id } - }catch (Exception e){ + } catch (Exception e) { + log.info "failed parse : ${json}" + throw e; + } + } + + + static List parseAllWithGroupLatestResponse(Map json) { + try { + return json.response.docs.collect { new MavenId(it.id + ':' + it.latestVersion) } + } catch (Exception e) { log.info "failed parse : ${json}" throw e; } } - static List parseAllWithGroupLatestResponse(Object json){ + List parseAllWithGroupLatestResponse2(Map json) { try { - return json.response.docs.collect { new MavenId(it.id +':'+ it.latestVersion) } - }catch (Exception e){ + List docs = json.response.docs; + if (docs.size() == 0) { + throw new IllegalArgumentException("No docs found in ${json}") + } + docs = docs.findAll { isDocMatched(it) } + return docs.collect { new MavenId(it.id + ':' + it.latestVersion) } + } catch (Exception e) { log.info "failed parse : ${json}" throw e; } } + + /** + * key value + * a azure-storage-queue + * ec ArrayList(4) = [-sources.jar, -javadoc.jar, .jar, .pom] + * g com.azure + * id com.azure:azure-storage-queue + * latestVersion 12.2.0 + * p jar + * repositoryId central + * text ArrayList(6) = [com.azure, azure-storage-queue, -sources.jar, -javadoc.jar, .jar, .pom] + * timestamp 1578943729000 + * versionCount 8 + */ + boolean isDocMatched(Map json) { + long ts = json.timestamp; + return isDocMatched2(json, new Date(ts)); + } + + boolean isDocMatched2(Map json, Date lastUploadTime) { + boolean accepted = false + if (json.p == 'jar') { + if (acceptOnlyAfterDate == null) { + accepted = true; + } else { + accepted = lastUploadTime.getTime() > acceptOnlyAfterDate.getTime(); + } + } + return accepted; + } + } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenSearch.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenSearch.groovy index 546cf93f..80476927 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenSearch.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/classpath/search/MavenSearch.groovy @@ -20,16 +20,22 @@ class MavenSearch { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - static JsonSlurper slurper = new JsonSlurper() + public static JsonSlurper slurper = new JsonSlurper() + public static String mavenSearchSite = 'https://search.maven.org/solrsearch' - static List findMavenIdsAndDownload7(File file) { + public static String quote ='%22' + public static String space ='%20' + public int maxResultCountDefault = 100 + String defaultAndQuery = """ AND p:"jar" """.trim() + + List findMavenIdsAndDownload7(File file) { String hash = ClassPathCalculatorGroovyWithDownloadWise.calcSha1ForFile(file); return findMavenIdsAndDownload6(file, hash) } - static List findMavenIdsAndDownload6(File file, String hex) { - URL url = new URL("http://search.maven.org/solrsearch/select?q=1:%22${hex}%22&rows=3&wt=json") - Object result = slurper.parse(url) + List findMavenIdsAndDownload6(File file, String hex) { + URL url = new URL("${mavenSearchSite}/select?q=1:${quote}${hex}${quote}&rows=3&wt=json") + Map result = slurper.parse(url) as Map if (result == null) { throw new IllegalStateException("empty reply for ${file} ${hex}") } @@ -38,34 +44,55 @@ class MavenSearch { return response } + static String convertQueryToUrl(String query){ + query = query.replace(' ',space) + query = query.replace('"',quote) + return query + } + - static List findMavenIdsAllArtifactsWithGroupId(String groupId, int maxResultCount) { + + + Map findMavenIdsAllArtifactsWithGroupIdRaw(String groupId, int maxResultCount) { assert !groupId.contains(':') String groupId2 = URLEncoder.encode(groupId, "UTF8") - URL url = new URL("http://search.maven.org/solrsearch/select?q=g:%22${groupId2}%22&rows=${maxResultCount}&wt=json") - java.lang.Object result = slurper.parse(url) - assert result != null: url - List response = MavenResponseParser.parseAllWithGroupLatestResponse(result); + String searchByGroupQuery = """ "${groupId2}" ${defaultAndQuery} """.trim() + searchByGroupQuery = convertQueryToUrl(searchByGroupQuery) + String fullQuery = "${mavenSearchSite}/select?q=g:${searchByGroupQuery}&rows=${maxResultCount}&wt=json" + log.info "running : ${fullQuery} .." + URL url = new URL(fullQuery) + Map result = slurper.parse(url) as Map + return result; + } + + List findMavenIdsAllArtifactsWithGroupId(String groupId, int maxResultCount) { + Map raw = findMavenIdsAllArtifactsWithGroupIdRaw(groupId, maxResultCount) + List response = MavenResponseParser.parseAllWithGroupLatestResponse(raw); return response; + } + List findMavenIdsWithGroupIdAndHasJar(String groupId, int maxResultCount) { + Map raw = findMavenIdsAllArtifactsWithGroupIdRaw(groupId, maxResultCount) + List response = new MavenResponseParser().parseAllWithGroupLatestResponse2(raw); + return response; } - static List findMavenIdsAllArtifactsWithGroupId(String groupId) { - return findMavenIdsAllArtifactsWithGroupId(groupId, 30) + + List findMavenIdsAllArtifactsWithGroupId(String groupId) { + return findMavenIdsAllArtifactsWithGroupId(groupId, maxResultCountDefault) } - static void findNonEmptyMavenIdsAllArtifactsWithGroupId(AddFilesToClassLoaderCommon adder, String groupId) { + void findNonEmptyMavenIdsAllArtifactsWithGroupId(AddFilesToClassLoaderCommon adder, String groupId) { List mavenIds = findMavenIdsAllArtifactsWithGroupId(groupId) MavenDependenciesResolver dependenciesResolver = MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver mavenIds = mavenIds.findAll { dependenciesResolver.resolveAndDownloadDeepDependencies(it, false, true).find { MavenId m -> adder.mavenCommonUtils.findMavenOrGradle(m) != null } != null } adder.addAllWithDeps mavenIds - } - static void findMavenIdsAndDownload1(File groovyFile) { + void findMavenIdsAndDownload1(File groovyFile) { LongTaskInfo longTaskInfo = new LongTaskInfo() ClassPathCalculatorGroovyWise calculatorGroovyWise = new ClassPathCalculatorGroovyWise(longTaskInfo) calculatorGroovyWise.calcMavenCache() @@ -77,7 +104,7 @@ class MavenSearch { findMavenIdsAndDownload3(files, longTaskInfo) } - static void findMavenIdsAndDownload3(List files, LongTaskInfo longTaskInfo) { + void findMavenIdsAndDownload3(List files, LongTaskInfo longTaskInfo) { FindMavenIdsAndDownload d = new FindMavenIdsAndDownload() files.each { diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/enumutils/EnumCustomNameResolver.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/enumutils/EnumCustomNameResolver.groovy new file mode 100644 index 00000000..e6bfadfa --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/enumutils/EnumCustomNameResolver.groovy @@ -0,0 +1,56 @@ +package net.sf.jremoterun.utilities.nonjdk.enumutils + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class EnumCustomNameResolver { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + static T resolveEx2(List values, String name) { + T t = resolve2(values, name) + if (t == null) { + throw new IllegalArgumentException("Failed find : ${name}, available : ${values}") + } + return t + } + + static T resolveEx(T[] values, String name) { + return resolveEx2(values.toList(),name) + } + + static T resolve(T[] values, String name) { + return resolve2(values.toList(),name) + } + + static T resolve2(List values, String name) { + for (Object val : values) { + EnumNameProvider res = (EnumNameProvider) val + if (res.getCustomName() == name) { + return (T) res + } + } + return null + } + + static Map createMap2(List values) { + Map res2 = [:] + for (T val : values) { + EnumNameProvider enum2 = (EnumNameProvider) val + T before = (T)res2.put(enum2.getCustomName(), val) + if (before != null) { + throw new IllegalStateException("Collision for ${val} and ${before}") + } + } + return res2 + + } + + static Map createMap(T[] values) { + return createMap2(values.toList()) + + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/enumutils/EnumNameProvider.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/enumutils/EnumNameProvider.groovy new file mode 100644 index 00000000..61b60400 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/enumutils/EnumNameProvider.groovy @@ -0,0 +1,13 @@ +package net.sf.jremoterun.utilities.nonjdk.enumutils + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +interface EnumNameProvider { + + String getCustomName(); + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/CloneGitRepo2.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/CloneGitRepo2.groovy deleted file mode 100644 index 42e71015..00000000 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/git/CloneGitRepo2.groovy +++ /dev/null @@ -1,113 +0,0 @@ -package net.sf.jremoterun.utilities.nonjdk.git - -import groovy.transform.CompileStatic -import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.nonjdk.GeneralUtils -import org.eclipse.jgit.api.FetchCommand -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.api.Status -import org.eclipse.jgit.api.StatusCommand -import org.eclipse.jgit.lib.Repository -import org.eclipse.jgit.transport.FetchResult -import org.eclipse.jgit.transport.RemoteConfig -import org.eclipse.jgit.transport.URIish - -import java.util.logging.Logger - -@CompileStatic -class CloneGitRepo2 { - - private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - - public static String gitNative = "git" - - - - static void addAllFiles(File dir) { - assert dir.exists() - GeneralUtils.runNativeProcess("${gitNative} add -A", dir, true) - log.info("finished git add") - } - - - static void gitCommit(File dir) { - String commit2 = "${gitNative} commit -m '${new Date().format('yyyy-MM-dd--HH-mm')}'" - try { - GeneralUtils.runNativeProcess(commit2, dir, true) - } catch (Exception e) { - log.info "${e}" - } - } - - static void updateGitRepo2(GitSpec gitSpec) { - File f = gitSpec.specOnly.resolveToFile() - String branch = gitSpec.branch - if (branch == null) { - branch = 'master' - } - updateGitRepo3(f, branch); - } - - static URIish getRemoteUri(Repository repository, String remoteName) { - if (remoteName == null) { - remoteName = org.eclipse.jgit.lib.Constants.DEFAULT_REMOTE_NAME; - } - RemoteConfig remoteConfig = new RemoteConfig(repository.getConfig(), remoteName) - List uRIs = remoteConfig.getURIs() - int size = uRIs.size() - switch (size) { - case 0: - throw new IllegalStateException("strange remote : ${remoteName}") - case 1: - return uRIs[0]; - default: - throw new IllegalStateException("Found ${size} remotes for ${remoteName} : ${uRIs}") - } - - } - - - static void fetch(File dir) { - Git git = Git.open(dir) - FetchCommand fetch = git.fetch() - CloneGitRepo4.runCustomize(fetch) - FetchResult fetchResult = fetch.call() - log.info("${fetchResult}") - } - - static void updateGitRepo3(File dir, String branch) { - fetch(dir) - updateGitRepo2(dir, branch) - } - - static void updateGitRepo2(File dir, String branch) { - Git git = Git.open(dir) - try { - StatusCommand statusCommand = git.status() - CloneGitRepo4.runCustomize(statusCommand) - Status statusResult = statusCommand.call() - log.info "${statusResult}" - log.info "Has uncommited : ${statusResult.hasUncommittedChanges()}" - log.info "Is clean : ${statusResult.isClean()}" - String gitStatus3 = "${gitNative} status" - GeneralUtils.runNativeProcess(gitStatus3, dir, true) - - log.info "conflict : ${statusResult.conflicting}" - log.info "modified : ${statusResult.modified}" - log.info "untacked : ${statusResult.untrackedFolders}" - log.info "missing : ${statusResult.missing}" - addAllFiles(dir) - gitCommit(dir) - - String branchName = "${branch}-${new Date().format("yyyy-MM-dd-HH-mm-ss")}" - - String cmd3 = "${gitNative} checkout -b ${branchName} origin/${branch}" - GeneralUtils.runNativeProcess(cmd3, dir, true) - } finally { - git.close() - - } - } - - -} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/CloneGitRepo4.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/CloneGitRepo4.groovy index 658a2e8c..aceb7166 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/git/CloneGitRepo4.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/CloneGitRepo4.groovy @@ -2,9 +2,7 @@ package net.sf.jremoterun.utilities.nonjdk.git import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.nonjdk.StringFindRange -import net.sf.jremoterun.utilities.nonjdk.StringUtils -import net.sf.jremoterun.utilities.nonjdk.git.GitSpec +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import org.apache.commons.io.FileUtils import org.eclipse.jgit.api.CloneCommand import org.eclipse.jgit.api.Git @@ -23,10 +21,11 @@ class CloneGitRepo4 { File gitBaseDir File gitTmpDir - public static GitCommandConfigure gitCommandConfigure + public static GitCommandConfigure gitCommandConfigure; + public GitProgressMonitorJrr progressMonitor = new GitProgressMonitorJrr(); - static void runCustomize(GitCommand gitCommand){ - if(gitCommandConfigure!=null){ + static void runCustomize(GitCommand gitCommand) { + if (gitCommandConfigure != null) { gitCommandConfigure.configure(gitCommand) } } @@ -39,13 +38,19 @@ class CloneGitRepo4 { assert gitTmpDir.exists() } - File cloneGitRepo3(GitSpec src) { + File getFileIfDownloaded(GitSpec src) { String dirSuffix = createGitRepoSuffix(src.repo) log.info "${dirSuffix}" - File toDir3 = new File(gitBaseDir, dirSuffix+'/git') + File toDir3 = new File(gitBaseDir, dirSuffix + '/'+src.checkoutDir) log.info "${toDir3}" + return toDir3 + } + + File cloneGitRepo3(GitSpec src) { + File toDir3 = getFileIfDownloaded(src) + cloneGitRepo4(src, toDir3); - File checkFile = new File(toDir3,'.git') + File checkFile = new File(toDir3, '.git') assert checkFile.exists() return toDir3; } @@ -63,7 +68,7 @@ class CloneGitRepo4 { } if (!tmpGitDir.renameTo(toDir3)) { log.info("can't rename ${tmpGitDir} to ${toDir3}, tring copy and delete") - FileUtils.copyDirectory(tmpGitDir, toDir3) + FileUtilsJrr.copyDirectory(tmpGitDir, toDir3) if (!FileUtils.deleteQuietly(tmpGitDir)) { log.info("failed delete ${tmpGitDir}") } @@ -94,23 +99,24 @@ class CloneGitRepo4 { } static String createGitRepoSuffix(String src) { - if(src.endsWith('.git')){ -// src.substring(0,) - src = src.substring(0, src.length() - 4 ) -// StringFindRange findRange=new StringFindRange(src) -// findRange.end =findRange.end-4 -// src = findRange.subStringInclusiveBoth() - log.info "new git ref = ${src}" - } + src = GitToSvnConverter.normalizeRepo(src); +// if (src.endsWith('.git')) { +//// src.substring(0,) +// src = src.substring(0, src.length() - 4) +//// StringFindRange findRange=new StringFindRange(src) +//// findRange.end =findRange.end-4 +//// src = findRange.subStringInclusiveBoth() +// log.info "new git ref = ${src}" +// } return UrlSymbolsReplacer.replaceBadSymbols(src) } void cloneGitRepo2(File toDir, GitSpec gitRef) { - cloneGitRepo(toDir,gitRef) + cloneGitRepo(toDir, gitRef) } - void custom( CloneCommand cloneCommand ){ + void custom(CloneCommand cloneCommand) { runCustomize(cloneCommand) } @@ -121,24 +127,26 @@ class CloneGitRepo4 { if (toDir.exists()) { assert toDir.listFiles().length == 0 } - CloneCommand cloneCommand = Git.cloneRepository() + final CloneCommand cloneCommand1 = Git.cloneRepository() + cloneCommand1.setProgressMonitor(progressMonitor) switch (gitRef) { case { gitRef.branch != null }: - cloneCommand.branch = gitRef.branch + cloneCommand1.setBranch(gitRef.branch) break case { gitRef.commitId != null }: case { gitRef.tag != null }: - throw new UnsupportedOperationException() + throw new UnsupportedOperationException(gitRef.toString()) break default: - cloneCommand.branch = 'master' + //cloneCommand1.branch = 'master' + break } - cloneCommand.setURI(gitRef.repo) + cloneCommand1.setURI(gitRef.repo) File gitDir = new File(toDir, ".git"); - cloneCommand.setGitDir(gitDir) - cloneCommand.directory = toDir - custom(cloneCommand) - Git gitCloneResult = cloneCommand.call() + cloneCommand1.setGitDir(gitDir) + cloneCommand1.directory = toDir + custom(cloneCommand1) + Git gitCloneResult = cloneCommand1.call() log.info "${gitCloneResult}" assert gitDir.listFiles().length > 1 assert toDir.listFiles().length > 0 diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/CommitApplier.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/CommitApplier.groovy new file mode 100644 index 00000000..19862581 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/CommitApplier.groovy @@ -0,0 +1,225 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.jgit.api.CommitCommand +import org.eclipse.jgit.diff.DiffEntry +import org.eclipse.jgit.revwalk.RevCommit +import org.eclipse.jgit.revwalk.RevSort +import org.eclipse.jgit.revwalk.RevWalk + +import java.util.logging.Logger; + +@CompileStatic +class CommitApplier { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public List revCommits; + public GitRepoUtils gitRepoUtils; + public List diffAppliers = [] + public List newRevCommits = []; + public HashSet modifiedAtStart; + public boolean includeSkippedCommits = true; + public static int maxSearch = 1000 + + + CommitApplier(List revCommits, GitRepoUtils gitRepoUtils) { + this.revCommits = revCommits + this.gitRepoUtils = gitRepoUtils + } + + + static CommitApplier calcRebaseCommitList(RevCommit branchCommit, RevCommit masterCommit, GitRepoUtils gitRepoUtils) { + List cherryPickList = new ArrayList<>(); + RevWalk r = new RevWalk(gitRepoUtils.gitRepository) + try { + r.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER, true); + r.sort(RevSort.COMMIT_TIME_DESC, true); + r.markUninteresting(r.lookupCommit(masterCommit)); + r.markStart(r.lookupCommit(branchCommit)); + Iterator commitsToUse = r.iterator(); + while (commitsToUse.hasNext()) { + RevCommit commit = commitsToUse.next(); + if (commit.getParentCount() == 1) { + cherryPickList.add(commit); + } + } + } finally { + r.close() + } + Collections.reverse(cherryPickList); + return new CommitApplier(cherryPickList, gitRepoUtils); + } + + static CommitApplier aaa(GitRepoUtils gitRepoUtils, String commitId, String parentCommit) { + List lisss = [] + gitRepoUtils.findCommit(parentCommit) + RevCommit rc = gitRepoUtils.findCommit(commitId) + lisss.add(0, rc) + for (i in 1.. lisss = [] + RevCommit rc = gitRepoUtils.findCommit(commitId) + lisss.add(0, rc) + for (i in 0.. manualPaths1 = getManualPaths() + Collection mergedPath = getMergedPath() + log.info "manualPaths = ${manualPaths1.size()} ${manualPaths1}" + log.info "mergedPaths = ${mergedPath.size()}" + Collection needBecareful = mergedPath.findAll { manualPaths1.contains(it) } + log.info "need be careful = ${needBecareful.size()} ${needBecareful}" + } + + + DiffApplier createDiffApplier(RevCommit parent, RevCommit childCommit) { + CommitIdCanonicalTreeParser iteratorParent = gitRepoUtils.getTreeIterator(parent.name()) + CommitIdCanonicalTreeParser iteratorChild = gitRepoUtils.getTreeIterator(childCommit.name()) + List entries = gitRepoUtils.diffStd(iteratorParent, iteratorChild) + DiffApplier diffApplier = createDiffApplier(entries, iteratorParent, iteratorChild) + return diffApplier; + } + + DiffApplier createDiffApplier(List entries, CommitIdCanonicalTreeParser iteratorParent, CommitIdCanonicalTreeParser iteratorChild) { + DiffApplier applier = DiffApplierFactory.factory1.create(entries, iteratorParent, iteratorChild, gitRepoUtils) ; + applier.onStatusKnown = { + checkModified(applier.modifiedBefore) + } + return applier + } + + void checkModified(HashSet modifiedBefore) { + if (modifiedAtStart == null) { + modifiedAtStart = modifiedBefore + } else { + if (modifiedAtStart != modifiedBefore) { + log.info("Internal error : modifiedAtStart = ${modifiedAtStart}, modifiedAfterStartAndBeforeThisCommid = ${modifiedBefore}") + throw new IllegalStateException("Internal error : modifiedAtStart = ${modifiedAtStart}, modifiedAfterStartAndBeforeThisCommid = ${modifiedBefore}") + } + } + } + + + void reApply(RevCommit revCommit) { + RevCommit parent = revCommit.getParent(0) + DiffApplier diff3 = createDiffApplier(parent, revCommit); + if (diff3.entriesOriginal.size() > 0) { + diffAppliers.add(diff3) + diff3.doStuff() + if (diff3.isHasSomethingToAdd()) { + CommitCommand commitCommand = gitRepoUtils.git.commit() + setCommitMsg(revCommit, commitCommand, diff3) + gitRepoUtils.doCustomGitTuning(commitCommand) + RevCommit revCommit1 = commitCommand.call() + newRevCommits.add(revCommit1) + } else { + onSkippedCommit(revCommit, diff3) + } + } else { + onSkippedCommit(revCommit, diff3) + } + } + + void onSkippedCommit(RevCommit revCommit, DiffApplier diff3) { + CommitCommand commitCommand = gitRepoUtils.git.commit() + commitCommand.setAllowEmpty(true) + gitRepoUtils.doCustomGitTuning(commitCommand) + setCommitMsgOnEmpty(revCommit,commitCommand,diff3) + if(includeSkippedCommits) { + RevCommit revCommit1 = commitCommand.call() + newRevCommits.add(revCommit1) + } + } + + void setCommitMsgOnEmpty(RevCommit revCommit, CommitCommand commitCommand, DiffApplier diff3) { + String msg + if (diff3.entriesOriginal.size() > 0) { + Set manualPaths33 = diff3.getManualPaths() + msg = "skip as found 0 files available to change ${revCommit.name()} ${revCommit.getFullMessage()}. Skipped entries : ${manualPaths33.size()} ${manualPaths33}" + log.info msg + } else { + msg = "skip as 0 files in commit ${revCommit.name()} ${revCommit.getFullMessage()}" + } + log.info msg + commitCommand.setMessage(msg) + } + + void setCommitMsg(RevCommit revCommit, CommitCommand commitCommand, DiffApplier diff3) { + Set manualPaths33 = diff3.getManualPaths() + List autoMerged = diff3.getByStatus(DiffApplier.DiffStatusEnum.modifiedConflictResolvedAuto); + Collection autoM = new HashSet<>() + autoMerged.each { + DiffEntryUtils.addBothEntryPaths(it, autoM) + } + autoM = autoM.sort() + String msg = "${revCommit.getShortMessage()} . Original commit : ${revCommit.name()}. AutoMerged ${autoM.size()} ${autoM} Skipped entries ${manualPaths33.size()} ${manualPaths33}" + commitCommand.setMessage(msg) + } + + List getAllDiffs() { + List result = [] + diffAppliers.each { + result.addAll(it.entriesOriginal) + } + return result + } + + Collection getAutoMergedPaths() { + List autoMergedObj = [] + TreeSet autoMergedS = new TreeSet<>() + diffAppliers.each { + autoMergedObj.addAll(it.getByStatus(DiffApplier.DiffStatusEnum.modifiedConflictResolvedAuto)) + autoMergedS.addAll() + autoMergedS.addAll(it.calcRemoved()) + } + autoMergedObj.each { + autoMergedS.add(it.getNewPath()) + } + return autoMergedS + } + + Collection getMergedPath() { + TreeSet skipped2 = new TreeSet<>() + diffAppliers.each { + skipped2.addAll(it.calcTouchedNow()) + skipped2.addAll(it.calcRemoved()) + } + return skipped2 + } + + TreeSet getManualPaths() { + TreeSet skipped2 = new TreeSet<>() + diffAppliers.each { + skipped2.addAll(it.getManualPaths()) + } + return skipped2 + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/CommitIdCanonicalTreeParser.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/CommitIdCanonicalTreeParser.groovy new file mode 100644 index 00000000..03f962c0 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/CommitIdCanonicalTreeParser.groovy @@ -0,0 +1,21 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.jgit.lib.ObjectId +import org.eclipse.jgit.treewalk.CanonicalTreeParser; + +import java.util.logging.Logger; + +@CompileStatic +class CommitIdCanonicalTreeParser extends CanonicalTreeParser{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public String name; + public ObjectId id ; + + CommitIdCanonicalTreeParser(String name, ObjectId id) { + this.name = name + this.id = id + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffApplier.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffApplier.groovy new file mode 100644 index 00000000..430b2e32 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffApplier.groovy @@ -0,0 +1,410 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.jgit.api.AddCommand +import org.eclipse.jgit.api.Status +import org.eclipse.jgit.api.StatusCommand +import org.eclipse.jgit.diff.DiffAlgorithm +import org.eclipse.jgit.diff.DiffEntry +import org.eclipse.jgit.diff.RawText +import org.eclipse.jgit.diff.RawTextComparator +import org.eclipse.jgit.dircache.DirCache +import org.eclipse.jgit.dircache.DirCacheEntry +import org.eclipse.jgit.lib.Constants +import org.eclipse.jgit.lib.ObjectDatabase +import org.eclipse.jgit.lib.ObjectId +import org.eclipse.jgit.lib.ObjectLoader +import org.eclipse.jgit.lib.Repository +import org.eclipse.jgit.merge.MergeAlgorithm +import org.eclipse.jgit.merge.MergeFormatter +import org.eclipse.jgit.merge.MergeResult +import org.eclipse.jgit.util.io.AutoCRLFOutputStream + +import java.nio.charset.StandardCharsets +import java.util.logging.Logger; + +@CompileStatic +class DiffApplier { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public List entriesOriginal; + public CommitIdCanonicalTreeParser iterator1; + public CommitIdCanonicalTreeParser iterator2; + public GitRepoUtils gitRepoUtils; + +// public List modified; +// public List added; +// public List copied; +// public List deleted; +// public List renamed; + +// public List consider = [] +// public List conflicted = [] +// public List skipped = []; + public IdentityHashMap diffStatus = new IdentityHashMap<>() + + public DirCache dirCache; + + public boolean resolveConflicstsAuto = true + public Status status1 + public HashSet modifiedBefore = new HashSet(); + public long maxFileSizeToMergeInKb = 1000; +// public HashSet addedNow = new HashSet(); +// public HashSet touchedNow = new HashSet(); + public MergeAlgorithm mergerAlgorithm = new MergeAlgorithm(); + public Map> conflictMergedResult = new IdentityHashMap<>() + public RawTextComparator mergeRawTextComparator = RawTextComparator.WS_IGNORE_ALL + public Runnable onStatusKnown + + DiffApplier(List entries, GitRepoUtils gitRepoUtils) { + this.entriesOriginal = entries + this.gitRepoUtils = gitRepoUtils + } + + + DiffApplier(List entriesOriginal, CommitIdCanonicalTreeParser iterator1, CommitIdCanonicalTreeParser iterator2, GitRepoUtils gitRepoUtils) { + this.entriesOriginal = entriesOriginal + this.iterator1 = iterator1 + this.iterator2 = iterator2 + this.gitRepoUtils = gitRepoUtils + } + + void setMergerAlgorithm(DiffAlgorithm.SupportedAlgorithm algorithm) { + mergerAlgorithm = new MergeAlgorithm(DiffAlgorithm.getAlgorithm(algorithm)); + } + + public static enum DiffStatusEnum { + modifiedNoConflict, + modifiedConflictUnknown, + modifiedConflictIssue, + modifiedConflictFileTooBig, + modifiedConflictResolvedAuto, + added, + copied, + deleted, + renamed, + ignored, + } + + List getByStatus(DiffStatusEnum statusEnum) { + return diffStatus.findAll { it.value == statusEnum }.collect { it.key } + } + + + void prepare() { + callStatus() + handleStatus() + readCache() + entriesOriginal.each { + DiffStatusEnum take = isOkToTake(it) + diffStatus.put(it, take) + } + } + + Set getManualPaths() { + TreeSet skippedS = new TreeSet<>() + getByStatus(DiffStatusEnum.ignored).each { + DiffEntryUtils.addBothEntryPaths(it, skippedS) + } + getByStatus(DiffStatusEnum.modifiedConflictIssue).each { + DiffEntryUtils.addBothEntryPaths(it, skippedS) + } + getByStatus(DiffStatusEnum.modifiedConflictFileTooBig).each { + DiffEntryUtils.addBothEntryPaths(it, skippedS) + } + getByStatus(DiffStatusEnum.modifiedConflictUnknown).each { + DiffEntryUtils.addBothEntryPaths(it, skippedS) + } + return skippedS + } + + void doStuff() { + prepare() + applyNewValues() + if (isHasSomethingToAdd()) { + addToIndex() + } + } + + boolean isHasSomethingToAdd() { + return calcTouchedNow().size() > 0 || calcRemoved().size() > 0 + } + + HashSet calcRemoved() { + HashSet res = new HashSet<>() + getByStatus(DiffStatusEnum.deleted).each { res.add(it.getOldPath()) } + getByStatus(DiffStatusEnum.renamed).each { res.add(it.getOldPath()) } + return res + } + + HashSet calcTouchedNow() { + HashSet res = new HashSet<>() + getByStatus(DiffStatusEnum.modifiedNoConflict).each { res.add(it.getNewPath()) } + getByStatus(DiffStatusEnum.modifiedConflictResolvedAuto).each { res.add(it.getNewPath()) } + getByStatus(DiffStatusEnum.added).each { res.add(it.getNewPath()) } + getByStatus(DiffStatusEnum.copied).each { res.add(it.getNewPath()) } + getByStatus(DiffStatusEnum.renamed).each { res.add(it.getNewPath()) } + return res + } + + HashSet calcAddedNow() { + HashSet res = new HashSet<>() + getByStatus(DiffStatusEnum.added).each { res.add(it.getNewPath()) } + getByStatus(DiffStatusEnum.copied).each { res.add(it.getNewPath()) } + getByStatus(DiffStatusEnum.renamed).each { res.add(it.getNewPath()) } + return res + } + + + void applyNewValues() { + getByStatus(DiffStatusEnum.modifiedNoConflict).each { applyNewValueEntry(it) } + getByStatus(DiffStatusEnum.added).each { + applyNewValueEntry(it) +// addedNow.add(it.getNewPath()) + } + getByStatus(DiffStatusEnum.copied).each { + applyNewValueEntry(it) +// addedNow.add(it.getNewPath()) + } + getByStatus(DiffStatusEnum.deleted).each { deletePath(it.getOldPath()) } + getByStatus(DiffStatusEnum.renamed).each { + applyNewValueEntry(it) + deletePath(it.getOldPath()) +// addedNow.add(it.getNewPath()) + } + if (resolveConflicstsAuto) { + getByStatus(DiffStatusEnum.modifiedConflictUnknown).each { + File f = new File(gitRepoUtils.gitBaseDir, it.getNewPath()); + if (f.size() > maxFileSizeToMergeInKb * 1000) { + diffStatus.put(it, DiffStatusEnum.modifiedConflictFileTooBig) + } else { + MergeResult res = resolveConflictAndApply(it) + conflictMergedResult.put(it, res) + if (res.containsConflicts()) { + diffStatus.put(it, DiffStatusEnum.modifiedConflictIssue) + } else { + diffStatus.put(it, DiffStatusEnum.modifiedConflictResolvedAuto) + } + } + } + + } + } + + + void callStatus() { + StatusCommand status = gitRepoUtils.git.status() + HashSet badPaths = new HashSet<>() + entriesOriginal.each { + DiffEntryUtils.addBothEntryPaths(it, badPaths) + } + badPaths.each { status.addPath(it) } + status1 = status.call() + } + + + void handleStatus() { + modifiedBefore.addAll(status1.getModified()) + modifiedBefore.addAll(status1.getUncommittedChanges()) + modifiedBefore.addAll(status1.getRemoved()) + modifiedBefore.addAll(status1.getMissing()) + if (onStatusKnown != null) { + onStatusKnown.run() + } + } + + DiffStatusEnum resolveStatus(DiffEntry entry) { + switch (entry.getChangeType()) { + case DiffEntry.ChangeType.MODIFY: + return DiffStatusEnum.modifiedNoConflict + case DiffEntry.ChangeType.ADD: + return DiffStatusEnum.added + case DiffEntry.ChangeType.COPY: + return DiffStatusEnum.copied + case DiffEntry.ChangeType.DELETE: + return DiffStatusEnum.deleted + case DiffEntry.ChangeType.RENAME: + return DiffStatusEnum.renamed + default: + throw new UnsupportedOperationException("${entry.getChangeType()} ${entry}") + } + } + + + boolean isAcceptOverride(String path) { + return false + } + + boolean isIgnoreOverride(String path) { + return false + } + +// TODO now white space diff will be applied, even if asked to ignore + MergeResult resolveConflictAndApply(DiffEntry entry) throws IOException { + assert entry.getChangeType() == DiffEntry.ChangeType.MODIFY + File f = new File(gitRepoUtils.gitBaseDir, entry.getNewPath()); + //DirCacheEntry entry1 = dirCache.getEntry(entry.getOldPath()) + ObjectDatabase db = gitRepoUtils.gitRepository.getObjectDatabase(); + try { + RawText baseText = new RawText(db.open(entry.getOldId().toObjectId(), Constants.OBJ_BLOB).getCachedBytes()); + RawText ourText = new RawText(f.bytes); + RawText theirsText = new RawText(db.open(entry.getNewId().toObjectId(), Constants.OBJ_BLOB).getCachedBytes()); + MergeResult mergeResult = mergerAlgorithm.merge(mergeRawTextComparator, baseText, ourText, theirsText); + if (!mergeResult.containsConflicts()) { + resolveConflictAndApply5(entry, mergeResult) + } + return mergeResult + } finally { + db.close() + } + } + + + //TODO verify opened and closed parenthers before writing to file + void resolveConflictAndApply5(DiffEntry entry, MergeResult merge) throws IOException { + MergeFormatter format = new MergeFormatter(); + File f = new File(gitRepoUtils.gitBaseDir, entry.getNewPath()); + BufferedOutputStream outputStream = f.newOutputStream() + OutputStream ooo = outputStream + AutoCRLFOutputStream aa = new AutoCRLFOutputStream(outputStream) + ooo = aa + format.formatMerge(ooo, merge, ["BASE", "OURS", "THEIRS"], StandardCharsets.UTF_8); + ooo.flush() + ooo.close() + } + + DiffStatusEnum isOkToTake(DiffEntry entry) { + String oldPath = entry.getOldPath() + String newPath = entry.getNewPath() + if (oldPath != null) { + if (isAcceptOverride(oldPath)) { + // TODO dangerous + return resolveStatus(entry) + } + if (isIgnoreOverride(oldPath)) { + return DiffStatusEnum.ignored + } + } + if (newPath != null) { + if (isAcceptOverride(newPath)) { + // TODO dangerous + return resolveStatus(entry) + } + if (isIgnoreOverride(newPath)) { + return DiffStatusEnum.ignored + } + } + if (isPathMatched(entry, modifiedBefore)) { + return DiffStatusEnum.ignored + } + switch (entry.getChangeType()) { + case DiffEntry.ChangeType.MODIFY: + DirCacheEntry entry1 = dirCache.getEntry(oldPath) + if (entry1 == null) { + return DiffStatusEnum.ignored + } + if (entry1.getObjectId().equals(entry.getOldId().toObjectId())) { + return DiffStatusEnum.modifiedNoConflict + } + return DiffStatusEnum.modifiedConflictUnknown + case DiffEntry.ChangeType.DELETE: + DirCacheEntry entry1 = dirCache.getEntry(oldPath) + if (entry1 == null) { + return DiffStatusEnum.ignored + } + if (entry1.getObjectId().equals(entry.getOldId().toObjectId())) { + return DiffStatusEnum.deleted + } + return DiffStatusEnum.ignored + case DiffEntry.ChangeType.ADD: + DirCacheEntry entry1 = dirCache.getEntry(newPath) + if (entry1 == null) { + return DiffStatusEnum.added + } + return DiffStatusEnum.ignored + case DiffEntry.ChangeType.RENAME: + DirCacheEntry entry1 = dirCache.getEntry(oldPath) + if (entry1 == null) { + return DiffStatusEnum.ignored + } + if (dirCache.getEntry(newPath) != null) { + return DiffStatusEnum.ignored + } + if (entry1.getObjectId().equals(entry.getOldId().toObjectId())) { + return DiffStatusEnum.renamed + } + return DiffStatusEnum.ignored + case DiffEntry.ChangeType.COPY: + DirCacheEntry entry1 = dirCache.getEntry(newPath) + if (entry1 == null) { + return DiffStatusEnum.copied + } + return DiffStatusEnum.ignored + default: + throw new IllegalArgumentException("${entry}") + } + } + + + void readCache() { + Repository repo = gitRepoUtils.gitRepository + dirCache = repo.readDirCache() + } + + void applyNewValueEntry(DiffEntry entry) { + File f = new File(gitRepoUtils.gitBaseDir, entry.getNewPath()); + File parentDir = f.getParentFile() + parentDir.mkdirs() + assert parentDir.exists() + BufferedOutputStream outputStream = f.newOutputStream() + ObjectLoader objectLoader = gitRepoUtils.gitRepository.open(entry.getNewId().toObjectId()) + objectLoader.copyTo(outputStream); + outputStream.flush() + outputStream.close(); +// touchedNow.add(entry.getNewPath()) + } + + void deletePath(String path) { + File f = new File(gitRepoUtils.gitBaseDir, path); + assert f.exists() + f.delete() + assert !f.exists() + } + + +// List findNoMatchedEntries(List entry, Collection paths) { +// return entry.findAll { !isPathMatched(it, paths) } +// } + + boolean isPathMatched(DiffEntry entry, Collection paths) { + return DiffEntryUtils.isAnyPathMatched(entry, paths) + } + + + void addToIndex() { + if (calcTouchedNow().size() > 0) { + addToIndex3(calcTouchedNow(), true) + } + addToIndex2(calcRemoved()) + addToIndex2(calcAddedNow()) + } + + + void addToIndex2(HashSet paths) { + if (paths.size() > 0) { + addToIndex3(paths, true) + addToIndex3(paths, false) + } + } + + void addToIndex3(HashSet paths, boolean setUpdated1) { + AddCommand addCommand = gitRepoUtils.git.add() + addCommand.setUpdate(setUpdated1) + gitRepoUtils.doCustomGitTuning(addCommand) + paths.each { addCommand.addFilepattern(it) } + dirCache = addCommand.call() + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffApplierFactory.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffApplierFactory.groovy new file mode 100644 index 00000000..310f8ced --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffApplierFactory.groovy @@ -0,0 +1,20 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.jgit.diff.DiffEntry; + +import java.util.logging.Logger; + +@CompileStatic +class DiffApplierFactory { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static DiffApplierFactory factory1 = new DiffApplierFactory() + + DiffApplier create(List entries, CommitIdCanonicalTreeParser iteratorParent, CommitIdCanonicalTreeParser iteratorChild,GitRepoUtils gitRepoUtils){ + DiffApplier applier = new DiffApplier(entries, iteratorParent, iteratorChild, gitRepoUtils) ; + return applier + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffEntryUtils.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffEntryUtils.groovy new file mode 100644 index 00000000..56ea27ac --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffEntryUtils.groovy @@ -0,0 +1,56 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.jgit.diff.DiffEntry; + +import java.util.logging.Logger; + +@CompileStatic +class DiffEntryUtils { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + + + static void addBothEntryPaths(DiffEntry entry, Collection paths) { + String oldPath = entry.getOldPath() + if(oldPath !=null){ + paths.add(oldPath) + } + String newPath = entry.getNewPath() + if(newPath !=null){ + paths.add(newPath) + } + } + + static boolean isAnyPathMatched(DiffEntry entry, String path) { + return entry.getOldPath() == path || entry.getNewPath() == path + } + + static boolean isAnyPathStartWith(DiffEntry entry, Collection paths) { + String find1 = paths.find { isAnyPathStartWith(entry, it) } + return find1!=null + } + + static boolean isAnyPathStartWith(DiffEntry entry, String path) { + String oldPath = entry.getOldPath() + if(oldPath !=null){ + if(oldPath.startsWith(path)){ + return true + } + } + String newPath = entry.getNewPath() + if(newPath !=null){ + if(newPath.startsWith(path)){ + return true + } + } + return false + } + + static boolean isAnyPathMatched(DiffEntry entry, Collection paths) { + String matcheddd = paths.find { isAnyPathMatched(entry, it) } + return matcheddd != null + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffFormatterJrr.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffFormatterJrr.groovy new file mode 100644 index 00000000..23871aa7 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffFormatterJrr.groovy @@ -0,0 +1,53 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.jgit.diff.DiffEntry +import org.eclipse.jgit.diff.DiffFormatter +import org.eclipse.jgit.dircache.DirCacheEntry +import org.eclipse.jgit.util.QuotedString; + +import java.util.logging.Logger + +import static org.eclipse.jgit.diff.DiffEntry.ChangeType.ADD +import static org.eclipse.jgit.diff.DiffEntry.ChangeType.DELETE +import static org.eclipse.jgit.lib.Constants.encode +import static org.eclipse.jgit.lib.Constants.encode +import static org.eclipse.jgit.lib.Constants.encodeASCII; + +@CompileStatic +class DiffFormatterJrr extends DiffFormatter { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static byte[] newLineBytes = '\n'.getBytes() + public static byte[] gitDiffBytes = "diff --git ".getBytes() + + + DiffFormatterJrr(OutputStream out) { + super(out) + } + + String getPath12(DiffEntry.ChangeType type, String oldPath, String newPath) { + switch (type) { + case DiffEntry.ChangeType.MODIFY: + return oldPath + case DiffEntry.ChangeType.DELETE: + return "${oldPath} ${type}" + case DiffEntry.ChangeType.ADD: + return "${newPath} ${type}" + case DiffEntry.ChangeType.RENAME: + return "${oldPath} ${type} ${newPath}" + case DiffEntry.ChangeType.COPY: + return "${newPath} ${type} from ${oldPath}" + default: + throw new IllegalArgumentException("${type} ${oldPath} ${newPath}") + } + } + + @Override + protected void formatGitDiffFirstHeaderLine(ByteArrayOutputStream o, DiffEntry.ChangeType type, String oldPath, String newPath) throws IOException { + String path = getPath12(type, oldPath, newPath); + o.write(encodeASCII("diff --git ")); //$NON-NLS-1$ + o.write(encode(QuotedString.GIT_PATH.quote(path))); + o.write(newLineBytes); + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffWriter.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffWriter.groovy new file mode 100644 index 00000000..59419d35 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/DiffWriter.groovy @@ -0,0 +1,99 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.jgit.diff.DiffEntry +import org.eclipse.jgit.diff.DiffFormatter +import org.eclipse.jgit.diff.RawTextComparator +import org.eclipse.jgit.treewalk.filter.TreeFilter; + +import java.util.logging.Logger + +@CompileStatic +class DiffWriter { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public List excludeChangeTypes = []; + public List entries + public GitRepoUtils gitRepoUtils; + public Collection includePaths; + public Collection excludePathsStartWith = []; + public Collection headers = []; + public Collection footers = []; + public TreeSet ignored = []; + + DiffWriter(List entries, GitRepoUtils gitRepoUtils) { + this.entries = entries + this.gitRepoUtils = gitRepoUtils + } + + boolean isEntryMatch(DiffEntry diffEntry) { + if (isEntryMatchImpl(diffEntry)) { + return true + } + DiffEntryUtils.addBothEntryPaths(diffEntry, ignored) + return false + } + + boolean isEntryMatchImpl(DiffEntry diffEntry) { + if (excludeChangeTypes.contains(diffEntry.getChangeType())) { + return false + } + if (DiffEntryUtils.isAnyPathStartWith(diffEntry, excludePathsStartWith)) { + return false + } + if (includePaths != null) { + if (DiffEntryUtils.isAnyPathMatched(diffEntry, includePaths)) { + return true + } + return false + } + return true + } + + void convertDiffToText(File file) { + BufferedOutputStream outputStream = file.newOutputStream() + DiffFormatterJrr formatter = createDiffDefaultFormatter(outputStream) + try { + writeHeader(outputStream) + convertDiffToText(formatter) + writeFooter(outputStream) + outputStream.flush() + } finally { + formatter.close() + outputStream.close() + } + } + + void writeHeader(OutputStream out1) { + headers.each { out1.write(it.getBytes());out1.write(DiffFormatterJrr.newLineBytes) } + } + + void writeFooter(OutputStream out1) { + if(ignored.size()>0){ + out1.write DiffFormatterJrr.gitDiffBytes + out1.write "ignored ${ignored.size()}\n".getBytes() + ignored.each {out1.write "${it}\n".getBytes()} + out1.write(DiffFormatterJrr.newLineBytes) + } + footers.each { out1.write(it.getBytes());out1.write(DiffFormatterJrr.newLineBytes) } + } + + DiffFormatterJrr createDiffDefaultFormatter(OutputStream out1) { + DiffFormatterJrr diffFormatter = new DiffFormatterJrr(out1) + diffFormatter.setDiffComparator(RawTextComparator.WS_IGNORE_ALL) + diffFormatter.setProgressMonitor(gitRepoUtils.progressMonitor) + diffFormatter.setPathFilter(TreeFilter.ALL) + diffFormatter.setRepository(gitRepoUtils.gitRepository) + return diffFormatter + } + + List findMatchedEntries() { + return entries.findAll { isEntryMatch(it) } + } + + void convertDiffToText(DiffFormatter diffFormatter) { + diffFormatter.format(findMatchedEntries()) + diffFormatter.flush() + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitBinaryAndSourceRef.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitBinaryAndSourceRef.groovy index 99f4ed1b..2731b1da 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitBinaryAndSourceRef.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitBinaryAndSourceRef.groovy @@ -4,6 +4,7 @@ import groovy.transform.Canonical import groovy.transform.CompileStatic import groovy.transform.Sortable import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import java.util.logging.Logger @@ -16,8 +17,8 @@ class GitBinaryAndSourceRef extends GitRef implements GitBinaryAndSourceRefRef { String src; - GitBinaryAndSourceRef(GitSpec repo, String bin, String src) { - super(repo, bin) + GitBinaryAndSourceRef(GitSpecRef repo, String bin, String src) { + super(repo.getGitSpec(), bin) this.src = src } @@ -40,4 +41,12 @@ class GitBinaryAndSourceRef extends GitRef implements GitBinaryAndSourceRefRef { GitBinaryAndSourceRef getRef() { return this } + + + + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this,child) + } + } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitProgressMonitorJrr.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitProgressMonitorJrr.groovy new file mode 100644 index 00000000..5665c9a3 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitProgressMonitorJrr.groovy @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2008-2010, Google Inc. and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils; + +import java.io.IOException; +import java.io.OutputStream; + +import org.eclipse.jgit.lib.BatchingProgressMonitor; +import org.eclipse.jgit.lib.Constants + +import java.util.logging.Logger; + +/** Write progress messages out to the sideband channel. */ +@CompileStatic +class GitProgressMonitorJrr extends BatchingProgressMonitor { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + GitProgressMonitorJrr() { + } + + @Override + void beginTask(String title, int work) { + log.info "starting ${title} , items: ${work}" + super.beginTask(title, work) + } + + @Override + void endTask() { + log.info "task ended" + super.endTask() + } +/** {@inheritDoc} */ + @Override + protected void onUpdate(String taskName, int workCurr) { + StringBuilder s = new StringBuilder(); + format(s, taskName, workCurr); + s.append(" \r"); //$NON-NLS-1$ + send(s); + } + + /** {@inheritDoc} */ + @Override + protected void onEndTask(String taskName, int workCurr) { + StringBuilder s = new StringBuilder(); + format(s, taskName, workCurr); + s.append(", done\n"); //$NON-NLS-1$ + send(s); + } + + private void format(StringBuilder s, String taskName, int workCurr) { + s.append(taskName); + s.append(": "); //$NON-NLS-1$ + s.append(workCurr); + } + + /** {@inheritDoc} */ + @Override + protected void onUpdate(String taskName, int cmp, int totalWork, int pcnt) { + StringBuilder s = new StringBuilder(); + format(s, taskName, cmp, totalWork, pcnt); + s.append(" \r"); //$NON-NLS-1$ + send(s); + } + + /** {@inheritDoc} */ + @Override + protected void onEndTask(String taskName, int cmp, int totalWork, int pcnt) { + StringBuilder s = new StringBuilder(); + format(s, taskName, cmp, totalWork, pcnt); + s.append("\n"); //$NON-NLS-1$ + send(s); + } + + private void format(StringBuilder s, String taskName, int cmp, + int totalWork, int pcnt) { + s.append(taskName); + s.append(": "); //$NON-NLS-1$ + if (pcnt < 100) + s.append(' '); + if (pcnt < 10) + s.append(' '); + s.append(pcnt); + s.append("% ("); //$NON-NLS-1$ + s.append(cmp); + s.append("/"); //$NON-NLS-1$ + s.append(totalWork); + s.append(")"); //$NON-NLS-1$ + } + + protected void send(StringBuilder s) { + log.info(s.toString()) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRef.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRef.groovy index afd427c3..d534e50c 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRef.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRef.groovy @@ -2,7 +2,11 @@ package net.sf.jremoterun.utilities.nonjdk.git import groovy.transform.Canonical import groovy.transform.Sortable; -import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef + import java.util.logging.Logger; import groovy.transform.CompileStatic; @@ -10,13 +14,15 @@ import groovy.transform.CompileStatic; @Canonical @CompileStatic @Sortable +@Deprecated class GitRef extends GitSpec implements GitRefRef{ private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); String pathInRepo; - GitRef(GitSpec repo, String pathInRepo) { + GitRef(GitSpecRef repo1, String pathInRepo) { + GitSpecRef repo = repo1.getGitSpec() this.repo = repo.repo this.branch = repo.branch this.commitId = repo.commitId @@ -36,7 +42,7 @@ class GitRef extends GitSpec implements GitRefRef{ @Override GitSpec getSpecOnly() { - GitSpec gitSpec = new GitSpec(repo,commitId,branch,tag) + GitSpec gitSpec = new GitSpec(repo, commitId, branch, tag) return gitSpec } @@ -44,4 +50,5 @@ class GitRef extends GitSpec implements GitRefRef{ GitRef getRef() { return this } + } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRefRef.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRefRef.groovy index c7e598f9..3b9145d5 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRefRef.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRefRef.groovy @@ -2,9 +2,11 @@ package net.sf.jremoterun.utilities.nonjdk.git import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +@Deprecated @CompileStatic -interface GitRefRef extends ToFileRef2 { +interface GitRefRef extends ToFileRef2, ChildFileLazy { GitRef getRef(); diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRemoteFind.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRemoteFind.groovy new file mode 100644 index 00000000..7a88d8a9 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRemoteFind.groovy @@ -0,0 +1,44 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.jgit.transport.URIish; + +import java.util.logging.Logger; +import net.sf.jremoterun.utilities.nonjdk.git.GitRepoUtils; + +@CompileStatic +abstract class GitRemoteFind { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + String detectRemote(GitRepoUtils gitRepoUtils){ + Set remoteNames = gitRepoUtils.gitRepository.getRemoteNames() + Map maps = [:] + Set reposss = remoteNames.findAll { + URIish uri = gitRepoUtils.getRemoteUri(it) + maps.put(it,uri) + if(uri==null){ + log.info "uri is null for ${it}" + return false + } + return isRepoGood(uri) + } + int size = reposss.size() + switch (size){ + case 0: + throw new Exception("no repo found from ${remoteNames}, available : ${maps}") + case 1: + return reposss.iterator().next() + default: + throw new Exception("many repo found ${reposss} : ${maps}") + } + } + + boolean isRepoGood(URIish urIish){ + String uri3 = urIish.getPath().replace('/', '') + return isRepoGood(uri3); + } + + abstract boolean isRepoGood(String uri3); + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRepoCheckoutFork.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRepoCheckoutFork.groovy new file mode 100644 index 00000000..57c17247 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRepoCheckoutFork.groovy @@ -0,0 +1,137 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.jgit.transport.RefSpec +import org.eclipse.jgit.transport.URIish +import net.sf.jremoterun.utilities.nonjdk.git.GitRepoUtils; + +import java.util.logging.Logger + +@CompileStatic +abstract class GitRepoCheckoutFork { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static boolean trimBrancheNameSpaces = true + + public String myUserName = System.getProperty('user.name'); + + public static String githubPrPrefix = 'pull' + public static String gitlabPrPrefix = 'merge-requests' + + + + GitRemoteFind orgRemoteFind = new GitRemoteFind() { + @Override + boolean isRepoGood(String uri3) { + return isOrgRemote1(uri3) + } + }; + + GitRemoteFind myRemoteFind = new GitRemoteFind() { + @Override + boolean isRepoGood(String uri3) { + return isMyRemote1(uri3) + } + }; + + File tmpDirBase; + + GitRepoCheckoutFork(File tmpDirBase) { + this.tmpDirBase = tmpDirBase + } + + + void checkoutBranch(GitRepoUtils gitRepoUtils, String newBranch, String originalBranch) { + checkoutBranch(gitRepoUtils, newBranch, originalBranch, true) + } + + RefSpec createRefSpec(String src,String target){ + return new RefSpec("${src}:${target}"); + } + + void checkoutPrCommon(GitRepoUtils gitRepoUtils, String newBranch, int prId, String prefix){ + if (newBranch == null) { + newBranch = gitRepoUtils.buildBranchName("pr_${prId}", new Date()) + } + String orgRemote = orgRemoteFind.detectRemote(gitRepoUtils); + String originalPath = "refs/remotes/${orgRemote}/${prefix}/${prId}" + RefSpec refSpec = createRefSpec("refs/${prefix}/${prId}/head",originalPath) + gitRepoUtils.fetch2(orgRemote,refSpec) + checkoutCoreRaw(gitRepoUtils,newBranch,originalPath,true) + } + + GitRepoUtils createGitRepoUtils(File repo){ + return new GitRepoUtils(repo); + } + + @Deprecated + void updatee(File repo, String newBranch, String originalBranch, boolean setMyRemote) { + assert repo.exists() + GitRepoUtils gitRepoUtils = createGitRepoUtils(repo); + checkoutBranch(gitRepoUtils,newBranch,originalBranch,setMyRemote) + } + + void checkoutBranch(GitRepoUtils gitRepoUtils, String newBranch, String originalBranch, boolean setMyRemote) { + if (originalBranch == null) { + originalBranch = 'master' + } + if(trimBrancheNameSpaces){ + originalBranch = originalBranch.trim() + } + if (newBranch == null) { + newBranch = gitRepoUtils.buildBranchName(originalBranch, new Date()) + } + + String orgRemote = orgRemoteFind.detectRemote(gitRepoUtils); + gitRepoUtils.fetch2(orgRemote,originalBranch); + String originalBranchPath = "remotes/${orgRemote}/${originalBranch}" + checkoutCoreRaw(gitRepoUtils,newBranch,originalBranchPath,setMyRemote) + +// URIish uri = gitRepoUtils.getRemoteUri(orgRemote) +// File tmpDir = tmpDirBase.child(uri.getPath().replace('/', '')) +// tmpDir.mkdir() +// gitRepoUtils.checkoutSavedDirtyFiles2(originalBranchPath, tmpDir, newBranch) +// if (setMyRemote) { +// gitRepoUtils.setRemote(null, myRemote) +// } +// gitRepoUtils.gitRepository.getConfig().save() + } + + void checkoutCoreRaw(GitRepoUtils gitRepoUtils, String newBranch, String originalPath, boolean setMyRemote) { + if (newBranch == null) { + throw new Exception("set branch name") + } + if(trimBrancheNameSpaces){ + newBranch = newBranch.trim() + originalPath = originalPath.trim() + } + + String orgRemote = orgRemoteFind.detectRemote(gitRepoUtils); + String myRemote; + if (setMyRemote) { + Set remoteNames1 = gitRepoUtils.gitRepository.getRemoteNames() + if (remoteNames1.size() < 2) { + // use to add new repo : git remote add nameOfRepo repoUrl + throw new Exception("too low remotes : ${remoteNames1}") + } + myRemote = myRemoteFind.detectRemote(gitRepoUtils); + } + URIish uri = gitRepoUtils.getRemoteUri(orgRemote) + File tmpDir = tmpDirBase.child(uri.getPath().replace('/', '')) + tmpDir.mkdir() + gitRepoUtils.checkoutSavedDirtyFiles2(originalPath, tmpDir, newBranch) + if (setMyRemote) { + gitRepoUtils.setRemote(null, myRemote) + } + gitRepoUtils.gitRepository.getConfig().save() + } + + abstract boolean isOrgRemote1(String uri); + + boolean isMyRemote1(String uri) { + return uri.startsWith(myUserName); + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRepoUtils.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRepoUtils.groovy new file mode 100644 index 00000000..22d248da --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitRepoUtils.groovy @@ -0,0 +1,605 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic +import net.sf.jremoterun.JrrUtils +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr +import net.sf.jremoterun.utilities.nonjdk.log.FileExtentionClass +import org.apache.commons.io.FileUtils +import org.codehaus.groovy.runtime.NullObject +import org.eclipse.jgit.api.* +import org.eclipse.jgit.diff.DiffEntry +import org.eclipse.jgit.dircache.DirCacheIterator +import org.eclipse.jgit.errors.NoRemoteRepositoryException +import org.eclipse.jgit.lib.Constants +import org.eclipse.jgit.lib.ObjectId +import org.eclipse.jgit.lib.ObjectReader +import org.eclipse.jgit.lib.Ref +import org.eclipse.jgit.lib.RefUpdate +import org.eclipse.jgit.lib.Repository +import org.eclipse.jgit.revwalk.FollowFilter +import org.eclipse.jgit.revwalk.RevCommit +import org.eclipse.jgit.revwalk.RevWalk +import org.eclipse.jgit.transport.FetchResult +import org.eclipse.jgit.transport.RefSpec +import org.eclipse.jgit.transport.RemoteConfig +import org.eclipse.jgit.transport.TrackingRefUpdate +import org.eclipse.jgit.transport.URIish +import org.eclipse.jgit.treewalk.AbstractTreeIterator +import org.eclipse.jgit.treewalk.TreeWalk +import org.eclipse.jgit.treewalk.WorkingTreeIterator +import org.eclipse.jgit.treewalk.filter.AndTreeFilter +import org.eclipse.jgit.treewalk.filter.IndexDiffFilter +import org.eclipse.jgit.treewalk.filter.NotIgnoredFilter +import org.eclipse.jgit.treewalk.filter.PathFilter +import org.eclipse.jgit.treewalk.filter.TreeFilter + +import java.text.SimpleDateFormat +import java.util.logging.Logger + +/** + Sync code with : + @see net.sf.jremoterun.utilities.nonjdk.firstdownload.specclassloader.GitRepoUtils2 + http://www.java2s.com/example/java-src/pkg/com/addthis/hydra/job/store/jobstoregit-17432.html + https://github.com/centic9/jgit-cookbook + https://www.baeldung.com/jgit + https://github.com/dmusican/Elegit + org.eclipse.jgit.pgm.Main + //https://github.com/centic9/jgit-cookbook/blob/master/src/main/java/org/dstadler/jgit/porcelain/ShowFileDiff.java + org.eclipse.jgit.transport.TransportHttp + */ +@CompileStatic +class GitRepoUtils implements AutoCloseable { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public File gitBaseDir; + public Git git; + public Repository gitRepository + public GitCommandConfigure gitCommandConfigure = CloneGitRepo4.gitCommandConfigure + public GitProgressMonitorJrr progressMonitor = new GitProgressMonitorJrr(); + private GitRepoUtils gitRepoUtils = this; + public static List badFetchResult = [RefUpdate.Result.IO_FAILURE, RefUpdate.Result.LOCK_FAILURE, RefUpdate.Result.REJECTED, + RefUpdate.Result.REJECTED_CURRENT_BRANCH, RefUpdate.Result.REJECTED_MISSING_OBJECT, RefUpdate.Result.REJECTED_OTHER_REASON] + public static String defaultBranchName = 'master' + + GitRepoUtils(GitSpecRef gitSpecRef) { + this(gitSpecRef.getGitSpec().resolveToFile()) + } + + GitRepoUtils(File gitBaseDir) { + this.gitBaseDir = gitBaseDir + if (!gitBaseDir.exists()) { + throw new FileNotFoundException(gitBaseDir.getAbsolutePath()); + } + assert gitBaseDir.isDirectory() + git = Git.open(gitBaseDir) + gitRepository = git.getRepository() + } + + void doCustomGitTuning(GitCommand gitCommand) { + if (gitCommandConfigure != null) { + gitCommandConfigure.configure(gitCommand) + } + } + + + CommitApplier calcRebaseCommitList(String branchCommit, String masterCommit) { + return CommitApplier.calcRebaseCommitList(findCommit(branchCommit), findCommit(masterCommit), this) + } + + + + void addAllFiles() { + AddCommand addCommand = git.add() + addCommand.addFilepattern('.') + doCustomGitTuning(addCommand) + addCommand.call() +// GeneralUtils.runNativeProcess("${gitNative} add -A", dir, true) + log.info("finished git add") + } + + void gitCommit() { + CommitCommand commitCommand = git.commit() + commitCommand.setAll(true) + SimpleDateFormat sdf = new SimpleDateFormat('yyyy-MM-dd--HH-mm') + String msg = "automsg-${sdf.format(new Date())}" + commitCommand.setMessage(msg) +// String commit2 = "${gitNative} commit -m '${new Date().format('yyyy-MM-dd--HH-mm')}'" +// try { + doCustomGitTuning(commitCommand) + commitCommand.call() +// GeneralUtils.runNativeProcess(commit2, dir, true) +// } catch (Exception e) { +// log.info "${e}" +// } + } + + RevCommit findCommit(String commitId) { + ObjectId commitIdObj = gitRepository.resolve(commitId) + if (NullObject.getNullObject().equals(commitIdObj)) { + throw new IllegalArgumentException("Not found : ${commitId}") + } + return gitRepository.parseCommit(commitIdObj) + + } + + + static void updateGitRepo2(GitSpecRef gitSpec1) { + GitSpec gitSpec = gitSpec1.gitSpec; + File f = gitSpec.specOnly.resolveToFile() + + String branch = gitSpec.branch + if (branch == null) { + branch = 'master' + } + GitRepoUtils gitRepoUtils = new GitRepoUtils(f) + gitRepoUtils.fetchAndCheckout(branch); + } + + + void deleteBranch(String... branchNames) { + String currentBranchShort = gitRepository.getBranch() + String currentBranchFull = gitRepository.getFullBranch() + List listBranches = branchNames.toList() + listBranches.each { + if (it == currentBranchFull) { + throw new Exception("tring delete current branch : ${it}") + } + if (it == currentBranchShort) { + throw new Exception("tring delete current branch : ${it}") + } + } + DeleteBranchCommand branchDelete = git.branchDelete() + branchDelete.setBranchNames(branchNames) + branchDelete.setForce(true) + doCustomGitTuning(branchDelete) + branchDelete.call() + } + + + void deleteOldBranches(String branchName, long dayBefore) { + long oneDay = 1000 * 3600 * 24 + long dateBefore = System.currentTimeMillis() - oneDay * dayBefore + deleteOldBranches(branchName, new Date(dateBefore)) + } + + void deleteOldBranches(String branchName, Date dateBefore) { + String currentBranchShort = gitRepository.getBranch() + String currentBranchFull = gitRepository.getFullBranch() + ListBranchCommand branchList = git.branchList() + doCustomGitTuning(branchList) + List refs = branchList.call() + String prefix = "refs/heads/${branchName}-"; + refs = refs.findAll { it.getName().startsWith(prefix) } + refs = refs.findAll { return ((it.getName() != currentBranchShort) && (it.getName() != currentBranchFull)) } + String branchName1 = 'refs/heads/' + buildBranchName(branchName, dateBefore) + refs = refs.findAll { it.getName().compareTo(branchName1) < 0 } + List refsHuman = refs.collect { it.getName().replace('refs/heads/', '') }.sort() + if (refsHuman.size() == 0) { + log.info "nothing to delete in ${gitBaseDir} for ${branchName} before date ${dateBefore}" + } else { + log.info "deleting : ${refsHuman}" + refs.each { + try { + deleteBranch(it.getName()) + } catch (Exception e) { + log.info "failed delete ${it} ${e}" + throw e + } + } + } + } + + void copyDirtyFiles(File copyToDir) { + assert copyToDir.exists() + StatusCommand statusCommand = git.status() + doCustomGitTuning(statusCommand) + Status status = statusCommand.call() + List filess = [] + filess.addAll status.getUntracked() + filess.addAll status.getUncommittedChanges() + filess = filess.unique().sort() + List files = filess.collect { gitBaseDir.child(it) }.findAll { it.isFile() } + files = files.findAll { it.exists() } + files.each { copyFile(gitBaseDir, copyToDir, it) } + } + + static copyFile(File gitDir, File copyToDir, File f) { + String pathToParent = FileExtentionClass.getPathToParent(gitDir, f) + File fileTo = copyToDir.child(pathToParent) + FileUtilsJrr.copyFile(f, fileTo) + } + + String getRemote(String branchName) { + if (branchName == null) { + branchName = getCurrentBranch() + } + String remote1 = gitRepository.getConfig().getString('branch', branchName, 'remote') + if (remote1 == null) { + throw new Exception("failed resolve remote for branch : ${branchName}") + } + return remote1 + } + + void setRemote(String branchName, String remoteName) { + if (branchName == null) { + branchName = getCurrentBranch() + } + gitRepository.getConfig().setString('branch', branchName, 'remote', remoteName) + } + + URIish getRemoteUri(String remoteName) { + if (remoteName == null) { + remoteName = org.eclipse.jgit.lib.Constants.DEFAULT_REMOTE_NAME; + } + RemoteConfig remoteConfig = new RemoteConfig(gitRepository.getConfig(), remoteName) + List uRIs = remoteConfig.getURIs() + int size = uRIs.size() + switch (size) { + case 0: + throw new IllegalStateException("strange remote : ${remoteName}") + case 1: + return uRIs[0]; + default: + throw new IllegalStateException("Found ${size} remotes for ${remoteName} : ${uRIs}") + } + + } + + String getCurrentBranch() { + return gitRepository.getBranch() + } + + + void fetchAllRemote() { + Set remoteNames = gitRepository.getRemoteNames() + remoteNames.each { + try { + fetch(it) + } catch (Exception e) { + Throwable e2 = JrrUtils.getRootException(e); + if (e2 instanceof NoRemoteRepositoryException) { + NoRemoteRepositoryException new_name = (NoRemoteRepositoryException) e2; + log.info("failed fetch ${it} : ${e}"); + } else { + throw e; + } + } + } + } + + + FetchResult fetch2(String remoteName, String branchName) { + assert remoteName != null + assert branchName != null + RefSpec refSpec = new RefSpec("refs/heads/${branchName}:refs/remotes/${remoteName}/${branchName}") + return fetch2(remoteName,refSpec) + } + + FetchResult fetch2(String remoteName, RefSpec refSpec) { + FetchCommand fetch1 = git.fetch() + fetch1.setProgressMonitor(progressMonitor) + fetch1.setRemote(remoteName) + List specs = [refSpec] + fetch1.setRefSpecs(specs) + doCustomGitTuning(fetch1) + FetchResult fetchResult = fetch1.call() + Collection trackingRefUpdates = fetchResult.getTrackingRefUpdates() + log.info "trackingRefUpdates size = ${trackingRefUpdates.size()}" + trackingRefUpdates.each { + handleFetchResult(it) + } + log.info("fetch done for ${gitBaseDir}") + return fetchResult + } + + FetchResult fetch(String remoteName) { + FetchCommand fetch1 = git.fetch() + if (remoteName != null) { + fetch1.setRemote(remoteName) + } + fetch1.setProgressMonitor(progressMonitor) + doCustomGitTuning(fetch1) + FetchResult fetchResult = fetch1.call() + Collection trackingRefUpdates = fetchResult.getTrackingRefUpdates() + log.info "trackingRefUpdates size = ${trackingRefUpdates.size()}" + trackingRefUpdates.each { + handleFetchResult(it) + } + log.info("fetch done for ${gitBaseDir}") + return fetchResult + } + + + + void handleFetchResult(TrackingRefUpdate trackingRefUpdate) { + String localName = trackingRefUpdate.getLocalName() + RefUpdate.Result result = trackingRefUpdate.getResult(); + log.info "${localName} ${result}" + if (badFetchResult.contains(result)) { + throw new Exception("failed fetch ${localName} ${result} ${trackingRefUpdate}") + } + } + + void fetchAndCheckout(String branch) { + fetch2(Constants.DEFAULT_REMOTE_NAME, branch) + checkoutAndCommitDirty2(branch, Constants.DEFAULT_REMOTE_NAME) + } + + + String buildBranchName(String branchName, Date date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss") + return "${branchName}-${sdf.format(new Date())}" + } + + void checkoutAndCommitDirty2(String branch, String remoteName) { + StatusCommand statusCommand = git.status() + doCustomGitTuning(statusCommand) + Status statusResult = statusCommand.call() + log.info "${gitBaseDir} is clean : ${statusResult.isClean()}" + if (!statusResult.isClean()) { + log.info "conflict : ${statusResult.conflicting}" + log.info "modified : ${statusResult.modified}" + log.info "untacked : ${statusResult.untrackedFolders}" + log.info "missing : ${statusResult.missing}" + addAllFiles() + gitCommit() + } + + + CreateBranchCommand branchCreate = git.branchCreate() + String branchName = buildBranchName(branch, new Date()) + branchCreate.setName(branchName) + branchCreate.setStartPoint("remotes/${remoteName}/${branch}") + doCustomGitTuning(branchCreate) + branchCreate.call() + + CheckoutCommand checkoutCommand = git.checkout() + checkoutCommand.setName(branchName) + doCustomGitTuning(checkoutCommand) + checkoutCommand.call() + } + + void checkoutSavedDirtyFiles(String originalBranchName, File copyToDir, String remoteName) { + String branchName = buildBranchName(originalBranchName, new Date()) + checkoutSavedDirtyFiles(originalBranchName, copyToDir, remoteName, branchName) + } + + Ref checkoutSavedDirtyFiles(String originalBranchName, File copyToDir, String remoteName, String branchName) { + String originalBranchPath = "remotes/${remoteName}/${originalBranchName}" + return checkoutSavedDirtyFiles2(originalBranchPath, copyToDir, branchName) + } + + + /** + * steps : + * 1. Copy dirty files to 'copyToDir' + * 2. create branch originalBranchName+currentDate + * 3. hard reset + * 4. checkout + * 5. Copy dirty files from 'copyToDir' + */ + Ref checkoutSavedDirtyFiles2(String startingPoint, File copyToDir, String newBranchName) { + if (getRefForBranch(newBranchName) != null) { + throw new Exception("Branch already exist : ${newBranchName}") + } + FileUtils.deleteQuietly(copyToDir) + copyToDir.mkdir() + assert copyToDir.exists() + assert copyToDir.listFiles().length == 0 + copyDirtyFiles(copyToDir) + + CreateBranchCommand branchCreate = git.branchCreate() + + branchCreate.setName(newBranchName) + branchCreate.setStartPoint(startingPoint) + doCustomGitTuning(branchCreate) + Ref newRef = branchCreate.call() + log.info "branch created ${newRef}" + + try { + ResetCommand resetCommand = git.reset() + resetCommand.mode = ResetCommand.ResetType.HARD + doCustomGitTuning(resetCommand) + resetCommand.call() + + CheckoutCommand checkoutCommand = git.checkout() + checkoutCommand.setName(newBranchName) + checkoutCommand.setForced(true) + doCustomGitTuning(checkoutCommand) + newRef = checkoutCommand.call() + } catch (Exception e) { + log.info "copiing files on exception ${e}" + FileUtilsJrr.copyDirectory(copyToDir, gitBaseDir) + throw e + } + + FileUtilsJrr.copyDirectory(copyToDir, gitBaseDir) + return newRef; + } + + /** + * + * @param startingPoint is name of local branch + */ + Ref checkoutSavedDirtyFiles3(String startingPoint, File copyToDir) { + FileUtils.deleteQuietly(copyToDir) + copyToDir.mkdir() + assert copyToDir.exists() + assert copyToDir.listFiles().length == 0 + copyDirtyFiles(copyToDir) + Ref newRef; + try { + ResetCommand resetCommand = git.reset() + resetCommand.mode = ResetCommand.ResetType.HARD + doCustomGitTuning(resetCommand) + resetCommand.call() + + CheckoutCommand checkoutCommand = git.checkout() + checkoutCommand.setName(startingPoint) + checkoutCommand.setForced(true) + doCustomGitTuning(checkoutCommand) + newRef = checkoutCommand.call() + } catch (Exception e) { + log.info "copiing files on exception ${e}" + FileUtilsJrr.copyDirectory(copyToDir, gitBaseDir) + throw e + } + + FileUtilsJrr.copyDirectory(copyToDir, gitBaseDir) + return newRef; + } + + /** + * @return if ref null then branch not exist + */ + Ref getRefForBranch(String branchName) { + Ref ref = gitRepository.findRef(branchName) + return ref + } + + void pull() { + StatusCommand statusCommand = git.status() + doCustomGitTuning(statusCommand) + Status statusResult = statusCommand.call() + log.info "${gitBaseDir} is clean : ${statusResult.isClean()}" + if (!statusResult.isClean()) { + log.info "conflict : ${statusResult.conflicting}" + log.info "modified : ${statusResult.modified}" + log.info "untacked : ${statusResult.untrackedFolders}" + log.info "missing : ${statusResult.missing}" + + ResetCommand resetCommand = git.reset() + resetCommand.mode = ResetCommand.ResetType.HARD + doCustomGitTuning(resetCommand) + resetCommand.call() + } + PullCommand pullCommand = git.pull(); + doCustomGitTuning(pullCommand) + pullCommand.call() + + } + + + CommitIdCanonicalTreeParser getTreeIterator(String name) throws IOException { + final ObjectId id = gitRepoUtils.gitRepository.resolve(name); + + if (NullObject.getNullObject().equals(id)) { + throw new IllegalArgumentException(name); + } + final CommitIdCanonicalTreeParser p = new CommitIdCanonicalTreeParser(name,id); + final ObjectReader or = gitRepoUtils.gitRepository.newObjectReader(); + try { + p.reset(or, new RevWalk(gitRepoUtils.gitRepository).parseTree(id)); + return p; + } finally { + or.close(); + } + } + + + DiffApplier revertCommit(String commitId) { + RevCommit rc = gitRepoUtils.findCommit(commitId) + return diff3(rc.name(), rc.getParent(0).name()) + } + + DiffApplier diff3(String a1, String a2) { + CommitIdCanonicalTreeParser iterator1 = getTreeIterator(a1) + CommitIdCanonicalTreeParser iterator2 = getTreeIterator(a2) + if(iterator1.id.name() == iterator2.id.name()){ + throw new IllegalArgumentException("point to same commit : ${a1} ${a2}") + } + List entries = diffStd(iterator1, iterator2) + return new DiffApplier(entries, iterator1,iterator2, this); + } + + DiffWriter createDiffWriter(String a1,String a2){ + DiffApplier diffApplier = diff3(a1, a2) + final ObjectId ida1 = gitRepoUtils.gitRepository.resolve(a1); + final ObjectId ida2 = gitRepoUtils.gitRepository.resolve(a2); + if(ida1.name() == ida2.name()){ + throw new IllegalArgumentException("point to same commit : ${a1} ${a2}") + } + DiffWriter diffWriter = new DiffWriter(diffApplier.entriesOriginal, this) + String aa1=a1 + String aa2=a2 + if(a1!=ida1.name()){ + aa1="${a1} ( ${ida1.name()} )" + } + if(a2!=ida2.name()){ + aa2="${a2} ( ${ida2.name()} )" + } + String datee = new SimpleDateFormat("YYYY-MM-dd").format(new Date()) + diffWriter.headers.add "${aa1} ${aa2} ${datee}".toString() + return diffWriter; + } + + + + List diffStd(AbstractTreeIterator a, AbstractTreeIterator b) { + DiffCommand diffCommand = git.diff() + diffCommand.setOldTree(a) + diffCommand.setNewTree(b) + return diffCommand.call() + } + + List diffFast(AbstractTreeIterator a, AbstractTreeIterator b) { + ObjectReader objectReader = gitRepoUtils.gitRepository.newObjectReader() + try { + List entries = diffImpl(a, b, TreeFilter.ALL, objectReader) + return entries + } finally { + objectReader.close() + } + } + + List diffImpl(AbstractTreeIterator a, AbstractTreeIterator b, TreeFilter pathFilter, ObjectReader reader) { + TreeWalk walk = new TreeWalk(gitRepoUtils.gitRepository, reader); + int aIndex = walk.addTree(a); + int bIndex = walk.addTree(b); + if (a instanceof WorkingTreeIterator && b instanceof DirCacheIterator) { + ((WorkingTreeIterator) a).setDirCacheIterator(walk, bIndex); + } else if (b instanceof WorkingTreeIterator && a instanceof DirCacheIterator) { + ((WorkingTreeIterator) b).setDirCacheIterator(walk, aIndex); + } + + walk.setRecursive(true); + + TreeFilter filter = getDiffTreeFilterFor(a, b); + if (pathFilter instanceof FollowFilter) { + walk.setFilter(AndTreeFilter.create( + PathFilter.create(((FollowFilter) pathFilter).getPath()), + filter)); + } else { + walk.setFilter(AndTreeFilter.create(pathFilter, filter)); + } + + //source = new ContentSource.Pair(source(a), source(b)); + + List files = DiffEntry.scan(walk); + return files; + } + + + TreeFilter getDiffTreeFilterFor(AbstractTreeIterator a, AbstractTreeIterator b) { + if (a instanceof DirCacheIterator && b instanceof WorkingTreeIterator) + return new IndexDiffFilter(0, 1); + + if (a instanceof WorkingTreeIterator && b instanceof DirCacheIterator) + return new IndexDiffFilter(1, 0); + + TreeFilter filter = TreeFilter.ANY_DIFF; + if (a instanceof WorkingTreeIterator) + filter = AndTreeFilter.create(new NotIgnoredFilter(0), filter); + if (b instanceof WorkingTreeIterator) + filter = AndTreeFilter.create(new NotIgnoredFilter(1), filter); + return filter; + } + + + @Override + void close() throws Exception { + git.close() + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitSpec.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitSpec.groovy index 550fc336..083977e8 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitSpec.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitSpec.groovy @@ -2,23 +2,29 @@ package net.sf.jremoterun.utilities.nonjdk.git import groovy.transform.Canonical import groovy.transform.CompileStatic +import groovy.transform.Sortable import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.CustomObjectHandler import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import java.util.logging.Logger @Canonical @CompileStatic -class GitSpec implements Serializable, ToFileRef2 { +@Sortable +class GitSpec implements Serializable, ToFileRef2, ChildFileLazy,GitSpecRef { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static String checkoutDirDefault = 'git'; String repo; String commitId; String branch; String tag; + String checkoutDir = checkoutDirDefault; GitSpec getSpecOnly() { return this @@ -33,5 +39,26 @@ class GitSpec implements Serializable, ToFileRef2 { return handler.resolveToFile(this) } +// File resolveToFileIfDownloaded() { +// CustomObjectHandler handler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler +// if(handler==null){ +// throw new IllegalStateException("customObjectHandler was not set") +// } +// return handler.resolveToFileIfDownloaded(this) +// } + + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this,child) + } + + @Override + GitSpec getGitSpec() { + return this + } + + SvnSpec convertToSvnRef(){ + return GitToSvnConverter.buildRef2(this) + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitSpecRef.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitSpecRef.groovy new file mode 100644 index 00000000..342375a0 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitSpecRef.groovy @@ -0,0 +1,16 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy; + +import java.util.logging.Logger; + +@CompileStatic +interface GitSpecRef extends ToFileRef2, ChildFileLazy{ + + GitSpec getGitSpec(); + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitToSvnConverter.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitToSvnConverter.groovy new file mode 100644 index 00000000..6b8d3846 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/GitToSvnConverter.groovy @@ -0,0 +1,56 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.StringFindRange; + +import java.util.logging.Logger; + +@CompileStatic +class GitToSvnConverter { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static String normalizeRepo(String repo) { + String prefix = repo; + if (prefix.endsWith('/')) { + StringFindRange sr = new StringFindRange(prefix); + sr.end = sr.end - 1; + prefix = sr.subStringInclusiveBoth() + } + if (prefix.endsWith('.git')) { + StringFindRange sr = new StringFindRange(prefix); + sr.end = sr.end - 4; + prefix = sr.subStringInclusiveBoth() + } + + return prefix + + } + + // see https://docs.github.com/en/github/importing-your-projects-to-github/support-for-subversion-clients + + + static SvnSpec buildRef2(GitSpec gitSpec) { + return new SvnSpec(buildRef(gitSpec)) + } + + static String buildRef(GitSpec gitSpec) { + String prefix = gitSpec.repo; + if (!prefix.startsWith('http')) { + throw new Exception('unsupported protocol : ' + prefix) + } + prefix = normalizeRepo(prefix); + if (gitSpec.branch != null) { + return prefix + '/branches/' + gitSpec.branch + } + if (gitSpec.tag != null) { + return prefix + '/tags/' + gitSpec.tag + } + if (gitSpec.commitId != null) { + throw new Exception('checkout by commit unsupported') + } + // if not add trunk, then will download all branches + return prefix + '/trunk'; + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/JrrGitSshFactory.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/JrrGitSshFactory.groovy deleted file mode 100644 index e0ffa2bf..00000000 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/git/JrrGitSshFactory.groovy +++ /dev/null @@ -1,51 +0,0 @@ -package net.sf.jremoterun.utilities.nonjdk.git - -import com.jcraft.jsch.JSch -import com.jcraft.jsch.JSchException -import com.jcraft.jsch.Session -import groovy.transform.CompileStatic; -import net.sf.jremoterun.utilities.JrrClassUtils -import org.eclipse.jgit.errors.TransportException -import org.eclipse.jgit.transport.CredentialsProvider -import org.eclipse.jgit.transport.JschConfigSessionFactory -import org.eclipse.jgit.transport.OpenSshConfig -import org.eclipse.jgit.transport.RemoteSession -import org.eclipse.jgit.transport.SshSessionFactory -import org.eclipse.jgit.transport.URIish -import org.eclipse.jgit.util.FS; - -import java.util.logging.Logger; - -@CompileStatic -class JrrGitSshFactory extends JschConfigSessionFactory { - private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - - public static boolean inited = false - - static void init() { - if(inited){ - - }else { - inited = true - JrrClassUtils.setFieldValue(SshSessionFactory, 'INSTANCE', new JrrGitSshFactory()) - JSch.setConfig("StrictHostKeyChecking", "no"); - } - } - - @Override - protected void configure(OpenSshConfig.Host hc, Session session) { - - } - - @Override - RemoteSession getSession(URIish uri, CredentialsProvider credentialsProvider, FS fs, int tms) throws TransportException { - return super.getSession(uri, credentialsProvider, fs, tms) - } - - @Override - protected JSch getJSch(OpenSshConfig.Host hc, FS fs) throws JSchException { - return super.getJSch(hc, fs) - } - - -} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/RemoteSessionGitJrr.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/RemoteSessionGitJrr.groovy new file mode 100644 index 00000000..2d9cf540 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/RemoteSessionGitJrr.groovy @@ -0,0 +1,19 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import com.jcraft.jsch.Session +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.jgit.transport.JschSession +import org.eclipse.jgit.transport.RemoteSession +import org.eclipse.jgit.transport.URIish; + +import java.util.logging.Logger; + +@CompileStatic +class RemoteSessionGitJrr extends JschSession{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + RemoteSessionGitJrr(Session session, URIish uri) { + super(session, uri) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnRef.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnRef.groovy index 0005a32b..d243ba47 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnRef.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnRef.groovy @@ -12,11 +12,11 @@ class SvnRef extends SvnSpec{ private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - String pathInRepo; + public String branch; - SvnRef(String repo, String pathInRepo) { - this.repo = repo - this.pathInRepo = pathInRepo + SvnRef(String repo, String branch) { + super(repo) + this.branch = branch } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnSpec.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnSpec.groovy index 3e202904..ba2f26e5 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnSpec.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnSpec.groovy @@ -6,17 +6,24 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.CustomObjectHandler import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import java.util.logging.Logger @Canonical @CompileStatic -class SvnSpec implements Serializable, ToFileRef2 { +class SvnSpec implements Serializable, SvnSpecRef { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - String repo; + public String repoPrefix = ''; + public final String repo; + public final boolean runExport = true; + SvnSpec(String repo) { + this.repo = repo + } @Override File resolveToFile() { @@ -28,5 +35,23 @@ class SvnSpec implements Serializable, ToFileRef2 { } + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this,child) + } + @Override + SvnSpec getSvnSpec() { + return this; + } + + SvnSpec buildChildRef(String subPath){ + String repo1= repo + + if(!repo1.endsWith('/')){ + repo1 = repo1+'/' + } + repo1 = repo1+subPath + return new SvnSpec(repo1) + } } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnSpecRef.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnSpecRef.groovy new file mode 100644 index 00000000..ded52467 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/git/SvnSpecRef.groovy @@ -0,0 +1,19 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import groovy.transform.Canonical +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.CustomObjectHandler +import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef + +import java.util.logging.Logger + + +@CompileStatic +interface SvnSpecRef extends ToFileRef2, ChildFileLazy { + + SvnSpec getSvnSpec(); +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/javacompiler/EclipseJavaCompilerPure.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/javacompiler/EclipseJavaCompilerPure.groovy index d7d3265b..c25fe8a5 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/javacompiler/EclipseJavaCompilerPure.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/javacompiler/EclipseJavaCompilerPure.groovy @@ -4,8 +4,10 @@ import groovy.io.FileType import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.AddFileToClassloaderDummy import net.sf.jremoterun.utilities.nonjdk.compiler3.eclipse.EclipseCompiler3 +import org.apache.commons.io.FileUtils import java.util.logging.Logger @@ -17,6 +19,7 @@ public class EclipseJavaCompilerPure { List files = [] EclipseCompiler3 compiler3; String javaVersion + public boolean rememberOutput = false; List additionalFlags = ['-g','-nowarn',] void addInDir(ToFileRef2 f ){ @@ -30,18 +33,22 @@ public class EclipseJavaCompilerPure { }else{ assert f.directory f.eachFileRecurse(FileType.FILES, { - File f2 = it as File - String name = f2.name - if (name.endsWith('.java')) { - files.add(f2) - } + addFileImpl(it) }) } } + void addFileImpl(File f2){ + String name = f2.name + if (name.endsWith('.java')) { + files.add(f2) + } + } + void checkOutDir(){ assert outputDir!=null + FileUtils.deleteQuietly(outputDir) outputDir.mkdir() assert outputDir.exists() outputDir.deleteDir() @@ -53,13 +60,19 @@ public class EclipseJavaCompilerPure { assert outputDir.listFiles().length == 0 } + StringWriter createCompiler( ){ + StringWriter javacOutput = new StringWriter(); + PrintWriter writer = new PrintWriter(javacOutput); + compiler3 = new EclipseCompiler3(writer, writer, false, null, null,rememberOutput) + return javacOutput + } + void compile() { assert javaVersion!=null checkOutDir() + files = files.unique(); String[] javacParameters = makeParameters(); - StringWriter javacOutput = new StringWriter(); - PrintWriter writer = new PrintWriter(javacOutput); - compiler3 = new EclipseCompiler3(writer, writer, false, null, null) + StringWriter javacOutput = createCompiler() boolean result = compile2(javacParameters) // log.info "result : ${result}" if (result) { @@ -83,6 +96,9 @@ public class EclipseJavaCompilerPure { private String[] makeParameters() { + if(files.size()==0){ + throw new Exception("No file to compile") + } LinkedList params = new LinkedList(); params.addAll(additionalFlags) params.add("-d"); diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/JavaStartTime.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/JavaStartTime.groovy new file mode 100644 index 00000000..058039f2 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/JavaStartTime.groovy @@ -0,0 +1,23 @@ +package net.sf.jremoterun.utilities.nonjdk.langutils + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import javax.management.MBeanServer +import java.lang.management.ManagementFactory +import java.lang.management.RuntimeMXBean; +import java.util.logging.Logger; + +@CompileStatic +class JavaStartTime { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static Date getStartTime(){ + RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean() + return new Date(runtimeMXBean.getStartTime()) + } + + + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/LangUtils.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/LangUtils.groovy new file mode 100644 index 00000000..0cbcb05c --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/LangUtils.groovy @@ -0,0 +1,70 @@ +package net.sf.jremoterun.utilities.nonjdk.langutils + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class LangUtils { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static String sys_paths = 'sys_paths' + public static String usr_paths = 'usr_paths' + + String[] getLibPathSystem() { + String[] res = JrrClassUtils.getFieldValue(ClassLoader, sys_paths) as String[]; + return res + } + + String[] getLibPathUser() { + String[] res = JrrClassUtils.getFieldValue(ClassLoader, usr_paths) as String[]; + if (res == null) { + log.info "lib not loaded" + } + return res + } + + void setLibToPathUnsafe(List path2, String fieldName) { + String[] array = path2.toArray(new String[0]) + JrrClassUtils.setFieldValue(ClassLoader, fieldName, array) + } + + void addLibToUserPath(File path2) { + addLibToUserPath2(path2, usr_paths) + } + + void addLibToUserPath2(File path2, String fieldName) { + assert path2.isDirectory() + List list = getLibPathUser().toList() + list.add(path2.absolutePath) + setLibToPathUnsafe(list, fieldName) + } + + void insertLibToUserPath(File path2) { + insertLibToUserPath2(path2, usr_paths) + } + + void insertLibToUserPath2(File path2, String fieldName) { + assert path2.isDirectory() + List list = getLibPathUser().toList() + list.add(0, path2.absolutePath) + setLibToPathUnsafe(list, fieldName) + + } + + // java.lang.ClassLoader.NativeLibrary is element + Vector getSystemNativeLibraries() { + Vector res = JrrClassUtils.getFieldValue(ClassLoader, 'systemNativeLibraries') as Vector; + return res + } + + Vector getSystemNativeLoadedLibraries() { + Vector res = JrrClassUtils.getFieldValue(ClassLoader, 'loadedLibraryNames') as Vector; + return res + } + + static void loadLibrary(Class fromClass, String libName, boolean isAbsolute) { + JrrClassUtils.invokeJavaMethod(ClassLoader, 'loadLibrary', fromClass, libName, isAbsolute); + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/NativeLibraryLoaderChecker.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/NativeLibraryLoaderChecker.groovy new file mode 100644 index 00000000..0f3dcf74 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/NativeLibraryLoaderChecker.groovy @@ -0,0 +1,32 @@ +package net.sf.jremoterun.utilities.nonjdk.langutils + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class NativeLibraryLoaderChecker { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + void loadLibrary(List pathToFiles, String libName) { + pathToFiles.each { + new LangUtils().insertLibToUserPath(it) + } + Runtime.getRuntime().loadLibrary(libName) + } + + /** + * Just libname + */ + void loadLibrary(String libName) { + Runtime.getRuntime().loadLibrary(libName) + } + + void loadByAbsolutPath(File pathToLib){ + assert pathToLib.exists(); + Runtime.getRuntime().load(pathToLib.getAbsolutePath()) + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/ObjectStringComparator.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/ObjectStringComparator.groovy new file mode 100644 index 00000000..c6e495e6 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/langutils/ObjectStringComparator.groovy @@ -0,0 +1,41 @@ +package net.sf.jremoterun.utilities.nonjdk.langutils + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ObjectStringComparator implements Comparator { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public boolean compareClassNameFirst = true + + @Override + int compare(Object lhs, Object rhs) { + if (lhs == null) { + if (rhs == null) { + return 0; + } + return -1; + } + if (rhs == null) { + return 1 + } + if (compareClassNameFirst) { + String lhsClass = lhs.getClass().getName() + String rhsClass = rhs.getClass().getName() + boolean classEquals = (lhsClass.equals(rhsClass)) + log.debug("${lhsClass} ${rhsClass} : ${classEquals}") + if (!classEquals) { + return lhsClass.compareToIgnoreCase(rhsClass) + } + } + String stringLeft = lhs.toString() + String stringRight = rhs.toString() + int result = stringLeft.compareToIgnoreCase(stringRight) + log.debug "${stringLeft} ${stringRight} : ${result}" + return result + } + + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/FilterOutputStreamJrr.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/FilterOutputStreamJrr.groovy new file mode 100644 index 00000000..1cc83dfa --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/FilterOutputStreamJrr.groovy @@ -0,0 +1,58 @@ +package net.sf.jremoterun.utilities.nonjdk.nativeprocess + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.commons.io.output.TeeOutputStream +import org.jetbrains.annotations.NotNull; + +import java.util.logging.Logger; + +@CompileStatic +class FilterOutputStreamJrr extends OutputStream { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public List allOut = [] + + public OutputStream out; + + + FilterOutputStreamJrr(OutputStream out) { + this.out = out; + } + + @Override + void write(@NotNull byte[] b, int off, int len) throws IOException { + out.write(b, off, len) + } + + @Override + void write(int b) throws IOException { + out.write(b) + } + + @Override + void write(@NotNull byte[] b) throws IOException { + out.write(b) + } + + @Override + void flush() throws IOException { + out.flush() + } + + @Override + void close() throws IOException { + out.close() + } + + void addNonClosableStream(OutputStream newOut){ + assert out != newOut + addStream(new NonClosableStream(newOut)); + } + + + void addStream(OutputStream newOut) { + assert out != newOut + out = new TeeOutputStream(out, newOut); + allOut.add(newOut) + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/NativeProcessResult.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/NativeProcessResult.groovy new file mode 100644 index 00000000..6623495d --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/NativeProcessResult.groovy @@ -0,0 +1,205 @@ +package net.sf.jremoterun.utilities.nonjdk.nativeprocess + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.BadExitCodeException +import net.sf.jremoterun.utilities.nonjdk.FileRotate +import net.sf.jremoterun.utilities.nonjdk.LastByteArrayOutputStream + +import java.util.logging.Level; +import java.util.logging.Logger; + +@CompileStatic +class NativeProcessResult { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public final Process process; + public final LastByteArrayOutputStream outLast = new LastByteArrayOutputStream(); + public final LastByteArrayOutputStream errLast = new LastByteArrayOutputStream(); + public final FilterOutputStreamJrr out2 = new FilterOutputStreamJrr(outLast); + public final FilterOutputStreamJrr err2 = new FilterOutputStreamJrr(errLast); + public Thread threadOut; + public Thread threadErr; + public volatile Integer exitCode; + public final Date startDate = new Date(); + public boolean exceptionOnError = true; + private volatile boolean waitAsync = false; + public volatile boolean continueRunning = true; + public volatile long timeoutInSec = 10 + + static List defaultEnv = createDefaultEnv2() + + + public Thread thread = new Thread() { + @Override + void run() { + doWaitImpl() + } + }; + + +// simple runner + static NativeProcessResult runNativeProcessAndWait(String cmd) { + runNativeProcessAndWait(cmd,null) + } + static NativeProcessResult runNativeProcessAndWait(String cmd, File runDir) { + if (runDir != null) { + assert runDir.exists() + } + Process process1 = cmd.execute(defaultEnv, runDir); + NativeProcessResult processResult = new NativeProcessResult(process1) { + @Override + void onTimeout() { + log.info "process running too long : ${cmd}" + } + }; + processResult.consumeOutStreamSysout() + processResult.waitWithPeriodicCheck() + return processResult + } + + + static List createEnvFromMap(Map getenv) { + return getenv.entrySet().collect { "${it.key}=${it.value}".toString() }; + } + + static List createDefaultEnv2() { + return createEnvFromMap(createDefaultEnv()) + } + + static Map createDefaultEnv() { + Map getenv = new Hashtable<>(System.getenv()); + getenv.remove('GROOVY_OPTS') + getenv.remove('groovypath') + getenv = getenv.findAll { it.key != null && it.key.length() > 0 && it.value != null && it.value.length() > 0 } + return getenv; + } + + + NativeProcessResult(Process process) { + this.process = process + } + + + void doWaitImpl() { + try { + exitCode = process.waitFor(); + waitIOThreadFinished() + if (waitAsync) { + onFinished(); + } + } catch (Throwable e) { + log.log(Level.SEVERE, "failed wait", e) + } + } + + void consumeOutStreamSysout() { + out2.addStream(new NonClosableStream(System.out)) + err2.addStream(new NonClosableStream(System.err)) + } + + + void addWriteOutToFile(File outputFile, int rotationDepth) { + FileRotate.rotateFile(outputFile, rotationDepth) + BufferedOutputStream outputStream2 = outputFile.newOutputStream() + out2.addStream(outputStream2) + err2.addStream(outputStream2) + } + + void consumeOutStream() { + if (threadOut != null) { + throw new Exception("Output already set") + } + threadOut = process.consumeProcessOutputStream(out2); + threadErr = process.consumeProcessErrorStream(err2); + } + + void onTimeout() {} + + void onFinishedFine() {} + + void closeOutStreams() { + try { + out2.flush() + } catch (Exception e) { + log.log(Level.SEVERE, "failed flush out stream", e) + } + try { + out2.flush() + } catch (Exception e) { + log.log(Level.SEVERE, "failed flush err stream", e) + } + try { + out2.close() + } catch (Exception e) { + log.log(Level.SEVERE, "failed close out stream", e) + } + try { + err2.close() + } catch (Exception e) { + log.log(Level.SEVERE, "failed close err stream", e) + } + } + + void onFinished() { + closeOutStreams() + if (exitCode == 0) { + onFinishedFine() + } else { + onBadExitCode() + } + } + + void onBadExitCode() { + if (exceptionOnError) { + String errOut = errLast.toString(); + String outOut = outLast.toString(); + throw new BadExitCodeException("Bad exit code = ${exitCode} : ${errOut},\n${outOut}"); + } else { + String errOut = errLast.toString() + String outOut = outLast.toString() + log.info "bad exit code ${exitCode} : ${errOut},\n${outOut}" + } + } + + + void waitAsyncM() { + waitAsync = true + if (threadOut == null) { + consumeOutStream(); + } + thread.start(); + } + + + void waitWithPeriodicCheck() { + if (threadOut == null) { + consumeOutStream(); + } + + thread.start(); + while (continueRunning) { + thread.join(timeoutInSec * 1000); + if (thread.isAlive()) { + onTimeout() + } else { + break + } + } + + assert !thread.isAlive() + onFinished() + } + + void waitIOThreadFinished() { + threadOut.join() + threadErr.join() + } + + @Override + String toString() { + return "alive=${thread.isAlive()} exitCode=${exitCode}, errStream=${errLast}, outStream=${outLast}"; + } + +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/NonClosableStream.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/NonClosableStream.groovy new file mode 100644 index 00000000..2d71c730 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/nativeprocess/NonClosableStream.groovy @@ -0,0 +1,21 @@ +package net.sf.jremoterun.utilities.nonjdk.nativeprocess + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.jetbrains.annotations.NotNull; + +import java.util.logging.Logger; + +@CompileStatic +class NonClosableStream extends FilterOutputStreamJrr{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + NonClosableStream(OutputStream out) { + super(out) + } + + @Override + void close() throws IOException { + + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/Servers.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/Servers.groovy index 7e7f2a39..0a3a9ebd 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/Servers.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/Servers.groovy @@ -2,6 +2,7 @@ package net.sf.jremoterun.utilities.nonjdk.sfdownloader /** * https://sourceforge.net/p/forge/documentation/Mirrors/ + * FIXME: issue with cert for all. */ enum Servers { @@ -26,6 +27,9 @@ enum Servers { ufpr('Curitiba, Brazil'), versaweb('Las Vegas, NV'), vorboss('London, United Kingdom'), + + + ; String description diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/SfLink.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/SfLink.groovy index 81f21238..b54ffc5e 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/SfLink.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/SfLink.groovy @@ -5,11 +5,13 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.CustomObjectHandler import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import java.util.logging.Logger @CompileStatic -class SfLink implements Serializable, ToFileRef2 { +class SfLink implements Serializable, ToFileRef2, ChildFileLazy { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); @@ -37,4 +39,10 @@ class SfLink implements Serializable, ToFileRef2 { } + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this,child) + } + + } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/SourceForgeDownloader.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/SourceForgeDownloader.groovy index f76fa4d1..27fa0fa7 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/SourceForgeDownloader.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/SourceForgeDownloader.groovy @@ -20,9 +20,13 @@ class SourceForgeDownloader { this.baseDir = baseDir } - File download(SfLink sfLink) { + File resolveIfDownloaded(SfLink sfLink) { String path2 = UrlSymbolsReplacer.replaceBadSymbols(sfLink.path) File f = new File(baseDir, path2) + return f + } + File download(SfLink sfLink) { + File f = resolveIfDownloaded(sfLink) if (f.exists()) { log.info "sf link ${sfLink} already downloaded" return f diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/UrlProvided.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/UrlProvided.groovy index 28952eba..c5d67142 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/UrlProvided.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/sfdownloader/UrlProvided.groovy @@ -1,7 +1,9 @@ package net.sf.jremoterun.utilities.nonjdk.sfdownloader +import net.sf.jremoterun.utilities.classpath.ToFileRef2 -interface UrlProvided { + +interface UrlProvided extends ToFileRef2{ URL convertToUrl(); } \ No newline at end of file diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBean.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBean.groovy index c3aed5c6..57775b97 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBean.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBean.groovy @@ -1,6 +1,11 @@ package net.sf.jremoterun.utilities.nonjdk.store +/** + * Save java bean like: + * bean.prop1 = value1; + * bean.prop2 = value2; + */ interface JavaBean { } \ No newline at end of file diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBean2.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBean2.groovy index 44edeb78..05f87ca1 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBean2.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBean2.groovy @@ -1,6 +1,9 @@ package net.sf.jremoterun.utilities.nonjdk.store - +/** + * Save java bean like : + * new JavaBean(field1:value1,field2:value2) + */ interface JavaBean2 { } \ No newline at end of file diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBeanStore.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBeanStore.groovy index c65ff039..64e2d7d4 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBeanStore.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/JavaBeanStore.groovy @@ -13,17 +13,32 @@ class JavaBeanStore { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); +// public static String varFieldName ='b' + + + Writer6Sub createWriter(JavaBean javaBean){ + return new Writer7Sub(javaBean.getClass()) + } + + ObjectWriter createObjectWriter(){ + return new ObjectWriter() + } + static String save3(JavaBean javaBean) { - Writer3Sub writer3 = new Writer3Sub() - ObjectWriter objectWriter = new ObjectWriter() + return new JavaBeanStore().saveS(javaBean) + } + + String saveS(JavaBean javaBean) { + Writer6Sub writer3 = createWriter(javaBean) + ObjectWriter objectWriter = createObjectWriter() Class beanClass = javaBean.class; writer3.addImport(beanClass) - writer3.body.add "${beanClass.simpleName} b = ${writer3.generateGetProperty(ClasspathConfigurator.varName)} as ${beanClass.simpleName};" as String +// writer3.body.add "${beanClass.simpleName} b = ${writer3.generateGetProperty(ClasspathConfigurator.varName)} as ${beanClass.simpleName};" as String if (javaBean instanceof JavaBeanCustomSaver) { JavaBeanCustomSaver customSaver = (JavaBeanCustomSaver) javaBean; - writer3.body.addAll customSaver.save('b', writer3, objectWriter) + writer3.body.addAll customSaver.save(Writer6Sub.varName, writer3, objectWriter) }else{ - writer3.body.addAll save('b', javaBean, writer3, objectWriter,false) + writer3.body.addAll save(Writer6Sub.varName, javaBean, writer3, objectWriter,false) } return writer3.buildResult() } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/ListStore.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/ListStore.groovy index f1826f7c..221e000c 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/ListStore.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/ListStore.groovy @@ -24,9 +24,18 @@ class ListStore { file.text = saveS(list) } + Writer3 createWriter(){ + return new Writer3Sub() + } + + ObjectWriter createObjectWriter(){ + return new ObjectWriter() + } + + String saveS(List list) { - Writer3 writer3 = new Writer3Sub() - ObjectWriter writer = new ObjectWriter() + Writer3 writer3 = createWriter() + ObjectWriter writer = createObjectWriter() writer3.addCreatedAtHeader() writer3.body.add "List b = ${writer3.generateGetProperty(varName)} as List;".toString() writer3.body.addAll list.collect { diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/MapStore.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/MapStore.groovy index 5a2408c3..fbb4662c 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/MapStore.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/MapStore.groovy @@ -1,8 +1,9 @@ package net.sf.jremoterun.utilities.nonjdk.store; import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.nonjdk.classpath.sl.GroovySettingsLoader; +import net.sf.jremoterun.utilities.nonjdk.classpath.sl.GroovySettingsLoader +import java.text.SimpleDateFormat; import java.util.logging.Logger; import groovy.transform.CompileStatic; @@ -31,7 +32,7 @@ class MapStore { }.join("\n") String s3 = """ -// created at ${new Date().format('yyyy-MM-dd HH:mm')} +// created at ${new SimpleDateFormat('yyyy-MM-dd HH:mm').format(new Date())} ; Map b = a ; ${s} """ diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/ObjectWriter.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/ObjectWriter.groovy index 51ae2693..0cac185a 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/ObjectWriter.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/ObjectWriter.groovy @@ -5,10 +5,17 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.BinaryWithSource import net.sf.jremoterun.utilities.classpath.BinaryWithSource2 import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepo import net.sf.jremoterun.utilities.classpath.MavenPath +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.GeneralBiblioRepository +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.RefLink import net.sf.jremoterun.utilities.nonjdk.git.GitBinaryAndSourceRef import net.sf.jremoterun.utilities.nonjdk.git.GitRef +import net.sf.jremoterun.utilities.nonjdk.git.SvnRef +import net.sf.jremoterun.utilities.nonjdk.git.SvnSpec import java.util.logging.Logger @@ -36,9 +43,16 @@ class ObjectWriter { case { obj instanceof URL }: writer3.addImport(URL) return " new URL('${obj}')" + return " new URL('${obj}')" case { obj instanceof MavenId }: writer3.addImport(MavenId) return " new MavenId('${obj}')" + case { obj instanceof GeneralBiblioRepository }: + GeneralBiblioRepository repo = obj as GeneralBiblioRepository + return write2ArgsConstructor(writer3,GeneralBiblioRepository, repo.name(),repo.url); + case { obj instanceof MavenIdAndRepo }: + MavenIdAndRepo mavenIdAndRepo = obj as MavenIdAndRepo + return write2ArgsConstructor(writer3,MavenIdAndRepo, mavenIdAndRepo.m,mavenIdAndRepo.repo); case { obj instanceof MavenPath }: writer3.addImport(MavenPath) return " new MavenPath('${obj}')" @@ -66,6 +80,17 @@ class ObjectWriter { String binary = writeObject(writer3, bs.pathInRepo) String source = writeObject(writer3, bs.src) return " new GitBinaryAndSourceRef(${repo}, ${binary}, ${source}) " + case { obj instanceof SvnRef }: + writer3.addImport(SvnRef) + SvnRef svnRef = obj as SvnRef + String repo = writeObject(writer3, svnRef.repo); + String branchS = writeObject(writer3, svnRef.branch); + return " new ${SvnRef.getSimpleName()} (${repo}, ${branchS}) " + case { obj instanceof SvnSpec }: + writer3.addImport(SvnSpec) + SvnSpec svnSpec = obj as SvnSpec + String repo = writeObject(writer3, svnSpec.repo); + return " new ${SvnSpec.getSimpleName()}( ${repo} ) " case { obj instanceof GitRef }: writer3.addImport(GitRef) GitRef gitRef = obj as GitRef @@ -78,10 +103,10 @@ class ObjectWriter { String value = ev.getName() return "${obj.class.simpleName}.getE( '${value}' )" case { obj instanceof String }: - return "'${obj}'" + return writeString(obj as String) case { obj instanceof File }: File f = obj as File - return "'${f.canonicalFile.absoluteFile.absolutePath.replace('\\', '/')}' as File"; + return "'${f.getCanonicalFile().getAbsoluteFile().getAbsolutePath().replace('\\', '/')}' as File"; case { obj instanceof Integer }: return "${obj}" case { obj instanceof List }: @@ -99,14 +124,90 @@ class ObjectWriter { case { obj instanceof JavaBean2 }: JavaBean2 bean2 = obj as JavaBean2; return JavaBeanStore2.save(bean2, writer3, this, false); + case { obj instanceof Class }: + return writeClass(writer3, (Class) obj) + case { obj instanceof Map }: + return writeSimpleMap(writer3, (Map) obj) + case { obj instanceof FileChildLazyRef }: + return writeFileChildLazyRef(writer3, obj as FileChildLazyRef) default: return writeUnknownObject(writer3, obj) } } + String writeFileChildLazyRef(Writer3 writer3,FileChildLazyRef ref){ + ToFileRef2 parentRef = ref.parentRef; + String parentRefS= writeObject(writer3, parentRef) + String childS = writeString(ref.child); + + if (parentRef instanceof ChildFileLazy) { + return " ${parentRefS}.childL(${childS}) " + } + writer3.addImport(FileChildLazyRef) + return " new ${FileChildLazyRef.getSimpleName()} ( ${parentRefS} , ${childS} ) "; + } + + String write2ArgsConstructor(Writer3 writer3, Class clazz,Object obj1,Object obj2) { + writer3.addImport(clazz) + String obj1S = writeObject(writer3, obj1) + String obj2S = writeObject(writer3, obj2) + return " new ${clazz.getSimpleName()}( ${obj1S}, ${obj2S} )" + } + + String writeString(String s){ + s = s.replace("\\","\\\\") + s = s.replace("'","\\'") + return "'${s}'" + } + + String writeClass(Writer3 writer3, Class clazz) { + String name1 = clazz.getName() +// log.info "${name1}" + int i = name1.indexOf('$') +// log.info "i = ${i}" + if (i > 0) { + int j = name1.lastIndexOf('.',i) + int k = name1.indexOf('$',j) + String begin = name1.substring(0, k) +// log.info "begin = ${begin}" + Class parentClass = clazz.getClassLoader().loadClass(begin) + writer3.addImport parentClass + + String remaining = name1.substring(j + 1).replace('$', '.') + return remaining; + } + writer3.addImport(clazz) + return clazz.getSimpleName() + } + + String writeSimpleMapComplex(Writer3 writer3, Map map) { + return writeSimpleMap(writer3, map) + } + + String writeSimpleMap(Writer3 writer3, Map map) { +// Map aa= [(1):2,(2):2] + Set> entries = map.entrySet() + String join = entries.collect { + String key = writeMapKey(writer3, map, it.key) + String value = writeMapKey(writer3, map, it.value) + return "(${key}) : ${value} ".toString() + }.join(',\n') + return '[' + join + ']' + } + + + String writeMapKey(Writer3 writer3, Map map, Object key) { + return writeObject(writer3, key) + } + + + String writeMapValue(Writer3 writer3, Map map, Object value) { + return writeObject(writer3, value) + } + String writeUnknownObject(Writer3 writer3, Object obj) { obj.class.getConstructor(String) - writer3.addImport(obj.class) + writer3.addImport(obj.getClass()) String asStr = writeObject(writer3, obj.toString()); return " new ${obj.class.simpleName} ( ${asStr} )" } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer3.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer3.groovy index 24c4fad9..103ae66a 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer3.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer3.groovy @@ -3,34 +3,71 @@ package net.sf.jremoterun.utilities.nonjdk.store import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import org.codehaus.groovy.control.CompilePhase +import org.codehaus.groovy.runtime.MethodClosure +import java.text.SimpleDateFormat import java.util.logging.Logger @CompileStatic class Writer3 { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static boolean addCompileStaticDefault = true List header = []; List importss = [] + List importsStatic = [] List body = []; + + boolean addCompileStatic = addCompileStaticDefault + Writer3() { } - void addCreatedAtHeader(){ - header.add "// created at ${new Date().format('yyyy-MM-dd HH:mm')}" as String + void addCreatedAtHeader() { + header.add "// created at ${new SimpleDateFormat('yyyy-MM-dd HH:mm').format(new Date())}" as String + } + + + List addAnotations() { + if (addCompileStatic) { + addImport(CompileStatic) + return ['@CompileStatic'] + } + return [] } String buildResult() { - List res = header + importss.collect { "import ${it} ;" as String} + [''] + body+[''] - String res3 = res.join('\n'); - GroovyFileChecker.analize(res3,CompilePhase.CANONICALIZATION, true ,false) + List res = header + importss.collect { "import ${it} ;" as String } + importsStatic.collect { + "import static ${it} ;" as String + } + ['',''] + body + [''] + String res3 = res.join('\n'); + GroovyFileChecker.analize(res3, CompilePhase.CANONICALIZATION, true, false) return res3; } + + void addImportStatic(MethodClosure methodClosure) { + Class owner = methodClosure.getOwner() as Class + addImportStatic(owner, methodClosure.getMethod()) + } + + void addImportStatic(Class clazz, String methodName) { + String sig = "${clazz.getName()}.${methodName}" + addImportStatic2 sig + } + + void addImportStatic2(String raw) { + if (importsStatic.contains(raw)) { + + } else { + importsStatic.add raw + } + } + void addImport(Class clazz) { if (importss.contains(clazz.name)) { @@ -39,8 +76,20 @@ class Writer3 { } } - String generateGetProperty(String propName){ + String generateGetProperty(String propName) { return " binding.getProperty('${propName}') " } + + void addParentMethodCall(ObjectWriter objectWriter, MethodClosure methodName, List args) { + addParentMethodCall(objectWriter, methodName.getMethod(), args) + } + + void addParentMethodCall(ObjectWriter objectWriter, String methodName, List args) { + Writer3 r3 = this + List args4 = args.collect { objectWriter.writeObject(r3, it) } + String r = "${methodName}( ${args4.join(',')} ) ;" + body.add r + } + } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer3Sub.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer3Sub.groovy index b3b1431b..8f52a29c 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer3Sub.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer3Sub.groovy @@ -15,6 +15,7 @@ class Writer3Sub extends Writer3{ String className = 'Config' + static MethodClosure doConfigMethod =(MethodClosure) GroovyRunnerConfigurator2.&doConfig; @@ -24,11 +25,12 @@ class Writer3Sub extends Writer3{ addImport(CompileStatic) } + @Override String buildResult() { List res = header + importss.collect { "import ${it} ;" as String}; // res += [''] -// res += ['@CompileStatic'] + addAnotations() res += ["class ${className} extends ${GroovyRunnerConfigurator2.simpleName} {" as String] // res += ["${className}(Binding bi){super(bi)}" as String] // res += ['@Override'] diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer4Sub.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer4Sub.groovy index 66b856fa..6d3c336f 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer4Sub.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer4Sub.groovy @@ -3,9 +3,6 @@ package net.sf.jremoterun.utilities.nonjdk.store import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy -import net.sf.jremoterun.utilities.groovystarter.ClasspathConfigurator -import net.sf.jremoterun.utilities.groovystarter.GroovyConfigLoader -import net.sf.jremoterun.utilities.groovystarter.GroovyRunnerConfigurator2 import java.util.logging.Logger diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer5Class.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer5Class.groovy index e3751535..3b683d15 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer5Class.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer5Class.groovy @@ -15,7 +15,7 @@ abstract class Writer5Class extends Writer3 { - String className = 'Config' + String classNameGenerated = 'Config' static MethodClosure addCpMethod = (MethodClosure) ClasspathConfigurator.&addCp; @@ -36,6 +36,7 @@ abstract class Writer5Class extends Writer3 { @Override String buildResult() { List res = header + importss.collect { "import ${it} ;" as String }; + addAnotations() res.add getClassDeclarationName() // res += ["${className}(Binding bi){super(bi)}" as String] // res += ['@Override'] diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer6Sub.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer6Sub.groovy index f4329447..1aecd4ea 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer6Sub.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer6Sub.groovy @@ -16,7 +16,7 @@ abstract class Writer6Sub extends Writer5Class { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); public static String className = 'Config' - public static String varName ='b' + public static String varName = 'b' Writer6Sub() { addImport(GroovyRunnerConfigurator2) @@ -24,17 +24,23 @@ abstract class Writer6Sub extends Writer5Class { addImport(ClasspathConfigurator) addImport(GroovyConfigLoader) addImport(AddFilesToClassLoaderGroovy) - addImport(getConfigClass()) } abstract Class getConfigClass(); + @Override + String buildResult() { + addImport(getConfigClass()) + return super.buildResult() + } + @Override String getClassDeclarationName() { - return "class ${className} extends ${GroovyConfigLoader.simpleName}<${getConfigClass().simpleName}> {".toString() + return "class ${classNameGenerated} extends ${GroovyConfigLoader.simpleName}<${getConfigClass().simpleName}> {".toString() } + @Override String getMainMethod() { MethodClosure method = GroovyConfigLoader.loadConfigMethod diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer7Sub.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer7Sub.groovy new file mode 100644 index 00000000..8f1d2982 --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/store/Writer7Sub.groovy @@ -0,0 +1,28 @@ +package net.sf.jremoterun.utilities.nonjdk.store + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy +import net.sf.jremoterun.utilities.groovystarter.ClasspathConfigurator +import net.sf.jremoterun.utilities.groovystarter.GroovyConfigLoader +import net.sf.jremoterun.utilities.groovystarter.GroovyRunnerConfigurator2 +import org.codehaus.groovy.runtime.MethodClosure + +import java.util.logging.Logger + +@CompileStatic +class Writer7Sub extends Writer6Sub { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + Class configClass ; + + Writer7Sub(Class configClass) { + this.configClass = configClass + } + + @Override + Class getConfigClass() { + return configClass + } +} diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/swing/JrrSwingUtils.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/swing/JrrSwingUtils.groovy index d6458e1b..b76689cf 100644 --- a/src-common/net/sf/jremoterun/utilities/nonjdk/swing/JrrSwingUtils.groovy +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/swing/JrrSwingUtils.groovy @@ -8,6 +8,7 @@ import net.sf.jremoterun.utilities.ObjectWrapper import javax.swing.* import java.awt.Component +import java.awt.Window import java.awt.event.FocusEvent import java.awt.event.FocusListener import java.util.concurrent.Callable @@ -20,6 +21,17 @@ class JrrSwingUtils { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + static void moveAllVisibleWindowToLeftUpperCorner() { + moveAllVisibleWindowTo(10, 10); + } + + static void moveAllVisibleWindowTo(int x, int y) { + invokeNowOrLaterInSwingThread { + Collection windows = JrrUtilities.findVisibleAwtWindows(); + windows.each { it.setLocation(x, y) } + } + } + static void invokeAndWaitInSwingThread(Callable callable) { if (SwingUtilities.isEventDispatchThread()) { callable.call() @@ -41,6 +53,7 @@ class JrrSwingUtils { static void invokeNowOrLaterInSwingThread(Callable callable) { + assert callable != null if (SwingUtilities.isEventDispatchThread()) { callable.call() } else { @@ -48,9 +61,13 @@ class JrrSwingUtils { SwingUtilities.invokeLater { try { callable.call() - }catch (Exception e){ + } catch (Throwable e) { // def string = JrrUtils.exceptionToString(stackTrace) - log.log(Level.SEVERE,"fail call invoke later", e); + log.log(Level.SEVERE, "fail call invoke later : ${callable.getClass().getName()}", e); + StackTraceElement[] trace = e.getStackTrace() + if (trace == null || trace.length == 0) { + log.severe("empty exception stack : ${e} ${callable.getClass().getName()}") + } } }; } @@ -73,5 +90,4 @@ class JrrSwingUtils { } - } diff --git a/src-common/net/sf/jremoterun/utilities/nonjdk/swing/QrCodeCreator.groovy b/src-common/net/sf/jremoterun/utilities/nonjdk/swing/QrCodeCreator.groovy new file mode 100644 index 00000000..49d232cd --- /dev/null +++ b/src-common/net/sf/jremoterun/utilities/nonjdk/swing/QrCodeCreator.groovy @@ -0,0 +1,95 @@ +package net.sf.jremoterun.utilities.nonjdk.swing + + +import com.google.zxing.BarcodeFormat +import com.google.zxing.EncodeHintType +import com.google.zxing.WriterException +import com.google.zxing.common.BitMatrix +import com.google.zxing.qrcode.QRCodeWriter +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities + +import javax.swing.* +import java.awt.* +import java.awt.image.BufferedImage +import java.util.logging.Level +import java.util.logging.Logger + +@CompileStatic +class QrCodeCreator extends JPanel { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public BufferedImage image; +// public int multFactor = 4 +// public ViewAndPanel viewAndPanel; + private QrCodeCreator qrCodeCreator = this; + + QrCodeCreator() { + setBorder(javax.swing.BorderFactory.createEtchedBorder()); + } + + @Override + protected void paintComponent(Graphics grphcs) { + super.paintComponent(grphcs); + if (image != null) { + grphcs.drawImage(image, 0, 0, null); + } + } + + protected void generateQrCodeImpl(String messsage) { + Hashtable hintMap = new Hashtable(); + hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); + hintMap.put(EncodeHintType.CHARACTER_SET, "UTF-8"); + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + int min1 = getSizeImage() + BitMatrix byteMatrix = qrCodeWriter.encode(messsage, BarcodeFormat.QR_CODE, min1, min1, hintMap); + int crunchifyWidth = byteMatrix.getWidth(); + image = new BufferedImage(crunchifyWidth, crunchifyWidth, BufferedImage.TYPE_INT_RGB); + image.createGraphics(); + Graphics2D graphics = (Graphics2D) image.getGraphics(); + graphics.setColor(Color.WHITE); + graphics.fillRect(0, 0, crunchifyWidth, crunchifyWidth); + graphics.setColor(Color.BLACK); + for (int i = 0; i < crunchifyWidth; i++) { + for (int j = 0; j < crunchifyWidth; j++) { + if (byteMatrix.get(i, j)) { + graphics.fillRect(i, j, 1, 1); + } + } + } + } + + void generateQrCode(String messsage) { + if (messsage == null || messsage.isEmpty()) { + image = null; + return; + } + try { + generateQrCodeImpl(messsage) + qrCodeCreator.repaint(); + } catch (WriterException ex) { + log.log(Level.SEVERE, 'failed write', ex); + JrrUtilities.showException('failed write', ex) + } + } + + int getSizeImage(){ + int width3 = getWidth(); + int height3 = getHeight() + int size12=Math.min(width3,height3) + return size12 + } + + int getWidth1() { + return getWidth() + } + + + int getHeight1() { + return getHeight() + } + + +} diff --git a/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/JavacJavaCompilerC.groovy b/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/JavacJavaCompilerC.groovy index 847f4014..b708c4c8 100644 --- a/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/JavacJavaCompilerC.groovy +++ b/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/JavacJavaCompilerC.groovy @@ -26,7 +26,7 @@ class JavacJavaCompilerC extends JavacJavaCompiler{ @Override void compile(List files, CompilationUnit cu) { Map options = config2.getJointCompilationOptions(); - def object = options.get('flags') + //def object = options.get('flags') // log.info "flags : ${object}" super.compile(files, cu) } diff --git a/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/javac/JavacCompilerFactoryC.groovy b/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/javac/JavacCompilerFactoryC.groovy index 7ec0d2de..9848bc79 100644 --- a/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/javac/JavacCompilerFactoryC.groovy +++ b/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/javac/JavacCompilerFactoryC.groovy @@ -2,6 +2,7 @@ package net.sf.jremoterun.utilities.nonjdk.compiler3.javac; import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.nonjdk.compiler3.GroovyCompiler +import net.sf.jremoterun.utilities.nonjdk.compiler3.GroovyCompilerParams import net.sf.jremoterun.utilities.nonjdk.compiler3.javac.JavacJavaCompiler2C import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.tools.javac.JavaCompiler @@ -18,15 +19,17 @@ class JavacCompilerFactoryC extends JavacCompilerFactory{ JavacJavaCompiler2C javaCompilerC ; - GroovyCompiler groovyCompiler + GroovyCompiler groovyCompiler; + GroovyCompilerParams params; - JavacCompilerFactoryC(GroovyCompiler groovyCompiler) { + JavacCompilerFactoryC(GroovyCompiler groovyCompiler, GroovyCompilerParams params) { this.groovyCompiler = groovyCompiler + this.params = params; } @Override JavaCompiler createCompiler(CompilerConfiguration config) { - javaCompilerC = new JavacJavaCompiler2C(config,groovyCompiler) + javaCompilerC = new JavacJavaCompiler2C(config,groovyCompiler,params) return javaCompilerC; } } diff --git a/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/javac/JavacJavaCompiler2C.groovy b/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/javac/JavacJavaCompiler2C.groovy index ca227113..cdfb66be 100644 --- a/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/javac/JavacJavaCompiler2C.groovy +++ b/src-compiler-jdk/net/sf/jremoterun/utilities/nonjdk/compiler3/javac/JavacJavaCompiler2C.groovy @@ -3,6 +3,7 @@ package net.sf.jremoterun.utilities.nonjdk.compiler3.javac import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.nonjdk.compiler3.GroovyCompiler +import net.sf.jremoterun.utilities.nonjdk.compiler3.GroovyCompilerParams import org.codehaus.groovy.control.CompilationUnit import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.messages.SimpleMessage @@ -17,12 +18,19 @@ public class JavacJavaCompiler2C implements JavaCompiler { private CompilerConfiguration config; // List additionalFlags = [] GroovyCompiler groovyCompiler; + GroovyCompilerParams params; - public JavacJavaCompiler2C(CompilerConfiguration config, GroovyCompiler groovyCompiler) { + public JavacJavaCompiler2C(CompilerConfiguration config, GroovyCompiler groovyCompiler,GroovyCompilerParams params) { this.config = config; this.groovyCompiler = groovyCompiler + this.params = params; + if(params==null){ + throw new NullPointerException('params is null') + } } + + public void compile(List files, CompilationUnit cu) { String[] javacParameters = makeParameters(files, cu.getClassLoader()); int result; @@ -131,7 +139,9 @@ public class JavacJavaCompiler2C implements JavaCompiler { // files to compile paras.addAll(files); - + if(this.params.printJavacArgs) { + log.info "javacArgs : ${params}" + } return paras.toArray(new String[paras.size()]); } diff --git a/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/classpathchecker/EclipseClassPathChecker.java b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/classpathchecker/EclipseClassPathChecker.java new file mode 100644 index 00000000..16df4966 --- /dev/null +++ b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/classpathchecker/EclipseClassPathChecker.java @@ -0,0 +1,68 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.classpathchecker; + +import java.util.logging.Logger; + +import org.apache.commons.logging.LogFactory; +import org.eclipse.osgi.internal.loader.EquinoxClassLoader; +import org.slf4j.LoggerFactory; + +import groovy.lang.GroovyObject; +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.classpath.ClRef; +import net.sf.jremoterun.utilities.nonjdk.classpath.tester.ClassPathTesterHelper2; +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollector; +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollectorI; + +public class EclipseClassPathChecker { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public ClassPathTesterHelper2 helper; + + public EclipseClassPathChecker(ClassPathTesterHelper2 helper) { + this.helper = helper; + } + + public EclipseClassPathChecker(ProblemCollectorI problemCollector) { + helper = new ClassPathTesterHelper2(problemCollector); + } + + public static void runChecks() { + ProblemCollector problemCollector = new ProblemCollector(); + EclipseClassPathChecker tester = new EclipseClassPathChecker(problemCollector); + tester.check(); + boolean allGood = problemCollector.checkIfProblemExistAndShowException(); + log.info("all good ? : " + allGood); + } + + public void check() { + EquinoxClassLoader currentClassLoader = (EquinoxClassLoader) JrrClassUtils.getCurrentClassLoader(); + checkImpl(currentClassLoader); + } + + ClRef jna = new ClRef("com.sun.jna.Callback"); + ClRef egitActivator = new ClRef("org.eclipse.egit.core.Activator"); + ClRef jgitActivator = new ClRef("org.eclipse.jgit.api.CloneCommand"); + ClRef svnOpActivator = new ClRef("org.tigris.subversion.subclipse.ui.operations.UpdateOperation"); + + + public void checkImpl(EquinoxClassLoader currentClassLoader) { + + helper.checkTheSameClassLoader5(org.apache.log4j.Logger.class, currentClassLoader); + helper.checkTheSameClassLoader5(LogFactory.class, currentClassLoader); + helper.checkTheSameClassLoader5(LoggerFactory.class, currentClassLoader); + helper.checkTheSameClassLoader5(javassist.ClassPath.class, currentClassLoader); +// helper.checkTheSameClassLoader5(sun.jvmstat.monitor.HostIdentifier.class, classLoaderParent, currentClassLoader); + + helper.checkNotSameClassLoader5(jna, currentClassLoader); + helper.checkNotSameClassLoader5(GroovyObject.class, currentClassLoader); + + + + + helper.checkNotSameClassLoader5(egitActivator, currentClassLoader); + helper.checkNotSameClassLoader5(jgitActivator, currentClassLoader); + helper.checkNotSameClassLoader5(svnOpActivator, currentClassLoader); + + } +} diff --git a/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/customrunners/CustomRunnersView.java b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/customrunners/CustomRunnersView.java new file mode 100644 index 00000000..4d2fe24a --- /dev/null +++ b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/customrunners/CustomRunnersView.java @@ -0,0 +1,194 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.customrunners; + +import java.io.File; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.logging.Logger; + +import org.apache.commons.io.FileUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.part.ViewPart; + +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.JrrUtilities; +import net.sf.jremoterun.utilities.OsInegrationClientI; +import net.sf.jremoterun.utilities.classpath.JrrGroovyScriptRunner; + +// +// +// +// +public class CustomRunnersView extends ViewPart { + + /** + * The ID of the view as specified by the extension. + */ + public static final String ID = CustomRunnersView.class.getName(); + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static Composite viewer; + + public static Composite parentView; + + @Override + public void createPartControl(Composite parent) { + parentView = parent; + log.info("Runner dir : " + runnersDir); + boolean dirSet = runnersDir != null; + if (dirSet) { + refresh3(); + } + + } + + public static File runnersDir; + + public static void setRunnerDirAndRefresh(File runnerDir2) throws Exception { + JrrUtilities.checkFileExist(runnerDir2); + runnersDir = runnerDir2; + log.info("do refresh " + runnerDir2); + boolean viewSet = parentView != null; + log.info("view set ? " + viewSet); + if (viewSet) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + refresh3(); + + } + }); + } + } + + public static JrrGroovyScriptRunner jrrGroovyScriptRunner = new JrrGroovyScriptRunner(); + public static OsInegrationClientI osInegrationClient; + + static void addRefershButton(Composite panel2) { + Button refreshB = new Button(panel2, SWT.PUSH); + refreshB.setText("Refresh"); +// panel2.add(openFileButton); + refreshB.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + refreshB.setEnabled(false); + try { + refresh3(); + } finally { + refreshB.setEnabled(true); + } + } + }); + } + + static void refresh3() { + try { + if (viewer != null) { + log.info("removing prev view .."); + viewer.dispose(); + viewer = null; + } + log.info("creating view .."); + viewer = new Composite(parentView, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setLayout(new RowLayout()); + refresh(viewer); + viewer.pack(); + } catch (Throwable e1) { + log.info(" " + e1); + JrrUtilities.showException("Failed refresh", e1); + } + } + + static void refresh(Composite panel2) { +// panel2.removeAll(); + addRefershButton(panel2); + File[] listFiles = runnersDir.listFiles(); + log.info("found files : " + listFiles.length + " : " + Arrays.toString(listFiles)); + + for (final File file : listFiles) { + if (file.isFile() && file.getName().endsWith(".groovy")) { + log.info("creating button for : " + file.getName()); + createActionButton(panel2, file); + Button openFileButton = new Button(panel2, SWT.PUSH); + openFileButton.setText("O"); +// panel2.add(openFileButton); + openFileButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + try { + log.info("opening file : " + file); + if(osInegrationClient==null) { + throw new NullPointerException("osInegrationClient is null"); + } + osInegrationClient.openFile(file, null); + } catch (Throwable e1) { + log.info(file.getName() + " " + e1); + JrrUtilities.showException(file.getName(), e1); + } + } + }); + + } + } + } + + static Button createActionButton(Composite parent, final File f) { + Button button = new Button(parent, SWT.PUSH); + button.setText(f.getName().replace(".groovy", "")); + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + try { + if (osInegrationClient != null) { + osInegrationClient.saveAllEditors(); + } + button.setEnabled(false); + Thread thread = new Thread("${f.name} custom runner") { + public void run() { + try { + log.info("file " + f.getName() + " calling .."); + Class clazz = jrrGroovyScriptRunner.createScriptClass( + FileUtils.readFileToString(f, Charset.defaultCharset()), f.getName()); + Thread.currentThread().setContextClassLoader(clazz.getClassLoader()); + Object instance = clazz.newInstance(); + JrrClassUtils.invokeJavaMethod(instance, "run"); + log.info("file " + f.getName() + " called"); + } catch (Throwable e) { + log.info(f.getName() + " " + e); + JrrUtilities.showException(f.getName(), e); + } finally { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + button.setEnabled(true); + } + }); + } + } + }; + thread.start(); + } catch (Throwable e2) { + log.info(f.getName() + " " + e2); + JrrUtilities.showException(f.getName(), e2); + } + } + }); + return button; + } + + @Override + public void setFocus() { + // log.info("request focus"); + viewer.setFocus(); + } +} diff --git a/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/init/AddIgnoreClasses.java b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/init/AddIgnoreClasses.java new file mode 100644 index 00000000..3547ca31 --- /dev/null +++ b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/init/AddIgnoreClasses.java @@ -0,0 +1,27 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.init; + +import java.util.logging.Logger; + +import org.eclipse.core.internal.runtime.RuntimeLog; +import org.eclipse.ui.internal.WorkbenchErrorHandlerProxy; +import org.eclipse.ui.statushandlers.StatusManager; + +import net.sf.jremoterun.utilities.JrrClassUtils; + +public class AddIgnoreClasses implements Runnable{ + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + public void run() { + init(); + } + + + public static void init() { + JrrClassUtils.ignoreClassesForCurrentClass.add(WorkbenchErrorHandlerProxy.class.getName()); + JrrClassUtils.ignoreClassesForCurrentClass.add(StatusManager.class.getName()); + JrrClassUtils.ignoreClassesForCurrentClass.add(RuntimeLog.class.getName()); + } + +} diff --git a/src-eclipse-showcmd/nik/git/forcepush/MyIDEWorkbenchErrorHandler.java b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/misc/MyIDEWorkbenchErrorHandler.java similarity index 78% rename from src-eclipse-showcmd/nik/git/forcepush/MyIDEWorkbenchErrorHandler.java rename to src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/misc/MyIDEWorkbenchErrorHandler.java index 13d07c52..f8029856 100644 --- a/src-eclipse-showcmd/nik/git/forcepush/MyIDEWorkbenchErrorHandler.java +++ b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/misc/MyIDEWorkbenchErrorHandler.java @@ -1,4 +1,4 @@ -package nik.git.forcepush; +package net.sf.jremoterun.utilities.nonjdk.eclipse.misc; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -10,34 +10,28 @@ import org.eclipse.core.internal.jobs.Worker; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.ui.application.IWorkbenchConfigurer; import org.eclipse.ui.internal.ide.IDEWorkbenchErrorHandler; import org.eclipse.ui.statushandlers.StatusAdapter; -import sun.reflect.Reflection; - public class MyIDEWorkbenchErrorHandler extends IDEWorkbenchErrorHandler { - private static final Logger log = Logger.getLogger(Reflection.getCallerClass(1).getName()); + private static final Logger log = Logger.getLogger(MyIDEWorkbenchErrorHandler.class.getName()); public boolean logStackTradeWhereStatusInvokedException = false; - public IDEWorkbenchErrorHandler handler; + public IDEWorkbenchErrorHandler nestedHandler; - public boolean supportsNotification(int type) { - return handler.supportsNotification(type); - } + private static SimpleDateFormat sdfDayHourMin = new SimpleDateFormat("dd HH:mm:ss"); - public int hashCode() { - return handler.hashCode(); - } + public MyIDEWorkbenchErrorHandler() { + super(null); + } - public Map getParams() { - return handler.getParams(); + public MyIDEWorkbenchErrorHandler(IDEWorkbenchErrorHandler nestedHandler) { + super(null); + this.nestedHandler = nestedHandler; } - public Object getParam(Object key) { - return handler.getParam(key); - } - private static SimpleDateFormat sdfDayHourMin = new SimpleDateFormat("dd HH:mm:ss"); public boolean isLogmsg(StatusAdapter statusAdapter, int style) { IStatus s = statusAdapter.getStatus(); @@ -69,7 +63,7 @@ public void handle(StatusAdapter statusAdapter, int style) { e.printStackTrace(); } if (propogate) { - handler.handle(statusAdapter, style); + nestedHandler.handle(statusAdapter, style); } } @@ -101,34 +95,46 @@ public void logMsg(IStatus s) { } } if (exception == null) { - log.info(sb+""); + log.info(sb + ""); } else { - log.log(Level.INFO, sb+"", exception); + log.log(Level.INFO, sb + "", exception); } } + public boolean supportsNotification(int type) { + return nestedHandler.supportsNotification(type); + } + + public int hashCode() { + return nestedHandler.hashCode(); + } + + public Map getParams() { + return nestedHandler.getParams(); + } + + public Object getParam(Object key) { + return nestedHandler.getParam(key); + } + public void setParams(Map params) { - handler.setParams(params); + nestedHandler.setParams(params); } public boolean equals(Object obj) { - return handler.equals(obj); + return nestedHandler.equals(obj); } public String getId() { - return handler.getId(); + return nestedHandler.getId(); } public void setId(String id) { - handler.setId(id); + nestedHandler.setId(id); } public String toString() { - return handler.toString(); - } - - public MyIDEWorkbenchErrorHandler() { - super(null); + return nestedHandler.toString(); } } diff --git a/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/misc/SetEclipseLogHandler.java b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/misc/SetEclipseLogHandler.java new file mode 100644 index 00000000..550249b7 --- /dev/null +++ b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/misc/SetEclipseLogHandler.java @@ -0,0 +1,55 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.misc; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.eclipse.jdt.internal.ui.wizards.buildpaths.SetFilterWizardPage; +import org.eclipse.ui.application.WorkbenchAdvisor; +import org.eclipse.ui.internal.Workbench; +import org.eclipse.ui.internal.ide.IDEWorkbenchErrorHandler; + +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.JrrUtilities3; +import nik.git.forcepush.jrr.JrrCommonEclipseBean; + +public class SetEclipseLogHandler { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static WorkbenchAdvisor workbenchAdvisorDefault; + public static IDEWorkbenchErrorHandler ideWorkbenchErrorHandlerDefault; + + public static IDEWorkbenchErrorHandler findIDEWorkbenchErrorHandler() throws Exception { + if (ideWorkbenchErrorHandlerDefault == null) { + ideWorkbenchErrorHandlerDefault = (IDEWorkbenchErrorHandler)findWorkbenchAdvisor().getWorkbenchErrorHandler(); + } + return ideWorkbenchErrorHandlerDefault; + } + + public static void setMyErrorHandler(WorkbenchAdvisor workbenchAdvisor,IDEWorkbenchErrorHandler errorHandler) throws Exception { + JrrClassUtils.setFieldValue(workbenchAdvisor, "ideWorkbenchErrorHandler", errorHandler); + } + + public static WorkbenchAdvisor findWorkbenchAdvisor() throws Exception { + if (workbenchAdvisorDefault == null) { + workbenchAdvisorDefault = (WorkbenchAdvisor) JrrClassUtils.getFieldValue(Workbench.getInstance(), + "advisor"); + } + return workbenchAdvisorDefault; + } + + + public static void setLogHandler() { + try { + IDEWorkbenchErrorHandler ideWorkbenchErrorHandler = findIDEWorkbenchErrorHandler(); + MyIDEWorkbenchErrorHandler errorHandler = new MyIDEWorkbenchErrorHandler(ideWorkbenchErrorHandler); + setMyErrorHandler(workbenchAdvisorDefault, errorHandler); + JrrClassUtils.ignoreClassesForCurrentClass.add(MyIDEWorkbenchErrorHandler.class.getName()); + } catch (Throwable e) { + JrrUtilities3.showException("eclipse 8 start 123", e); + e.printStackTrace(); + log.log(Level.SEVERE, null, e); + } + } + +} diff --git a/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/proxy/NoProxyEclipseProxyData.java b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/proxy/NoProxyEclipseProxyData.java new file mode 100644 index 00000000..b2ec9c84 --- /dev/null +++ b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/proxy/NoProxyEclipseProxyData.java @@ -0,0 +1,45 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.proxy; + +import java.net.URI; +import java.util.logging.Logger; +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.nonjdk.net.ProxyTrackerI; + +public class NoProxyEclipseProxyData implements EclipseProxyData{ + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public ProxyTrackerI proxyTracker; + + @Override + public String getPassword() { + return null; + } + + @Override + public String getUser() { + return null; + } + + @Override + public String getProxyHost() { + return null; + } + + @Override + public int getProxyPort() { + return 0; + } + + @Override + public boolean useProxyForHost(String host) { + proxyTracker.accessRequested(host, false); + return false; + } + + @Override + public boolean useProxy(URI uri) { + proxyTracker.accessRequested(uri, false); + return false; + } +} diff --git a/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/userlibconfig/UserLibraryConfigurator.java b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/userlibconfig/UserLibraryConfigurator.java new file mode 100644 index 00000000..99b63b78 --- /dev/null +++ b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/userlibconfig/UserLibraryConfigurator.java @@ -0,0 +1,62 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.userlibconfig; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.core.IClasspathAttribute; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.internal.core.ClasspathEntry; +import org.eclipse.jdt.internal.core.JavaModelManager; +import org.eclipse.jdt.internal.core.UserLibraryManager; + +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.AddFileWithSources; + +public class UserLibraryConfigurator extends AddFileWithSources { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public List binWithSources = new ArrayList(); + + public void saveLibraryToEclipseConfig(String libName) { + UserLibraryManager lm = JavaModelManager.getJavaModelManager().getUserLibraryManager(); + IClasspathEntry[] classpathEntries = binWithSources.toArray(new IClasspathEntry[0]); + lm.setUserLibrary(libName, classpathEntries, false); + } + + @Override + public void addLibraryWithSource(File bin, List src) throws Exception { + ClasspathEntry classpathEntry = createClasspathEntry(bin, src); + binWithSources.add(classpathEntry); + } + + protected ClasspathEntry createClasspathEntry(File bin1, List src1) { + Path binP = new Path(bin1.getAbsolutePath()); + Path srcP = null; + if (src1 != null && src1.size() > 0) { + File srcfile = src1.get(0); + if (srcfile != null) { + srcP = new Path(srcfile.getAbsolutePath()); + } + } + ClasspathEntry ce = new ClasspathEntry(IClasspathEntry.CPE_PROJECT, IClasspathEntry.CPE_LIBRARY, binP, + new IPath[0], new IPath[0], srcP, null, null, true, null, false, new IClasspathAttribute[0]); + return ce; + } + + @Override + public void addSourceFImpl(File arg0) throws Exception { + // TODO Auto-generated method stub + + } + + @Override + public void addSourceS(String arg0) throws Exception { + // TODO Auto-generated method stub + + } +} diff --git a/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/workingset/WorkingSetUpdate.java b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/workingset/WorkingSetUpdate.java new file mode 100644 index 00000000..8f300559 --- /dev/null +++ b/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/workingset/WorkingSetUpdate.java @@ -0,0 +1,41 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.workingset; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.ui.IWorkingSetManager; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.eclipse.ui.internal.WorkingSet; + +import net.sf.jremoterun.utilities.JrrClassUtils; + + + +public class WorkingSetUpdate { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + void sample() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + List adaptables = null; + WorkingSet ws = findWorkingSetByName("wsNameSample1"); + updateElements(ws, adaptables); + } + + public static void updateElements(WorkingSet workingSet, List adaptables) + throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + JrrClassUtils.setFieldValue(workingSet, "elements", new ArrayList(adaptables)); + } + + public static WorkingSet findWorkingSetByName(String name) { + IWorkingSetManager workingSetManager = WorkbenchPlugin.getDefault().getWorkingSetManager(); + return (WorkingSet) workingSetManager.getWorkingSet(name); + } + + + // org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceHyperlink +} diff --git a/src-eclipse-showcmd/nik/git/forcepush/MyEclipseClassLoaderHook.java b/src-eclipse-showcmd/nik/git/forcepush/MyEclipseClassLoaderHook.java index 02a809fb..770c2fd7 100644 --- a/src-eclipse-showcmd/nik/git/forcepush/MyEclipseClassLoaderHook.java +++ b/src-eclipse-showcmd/nik/git/forcepush/MyEclipseClassLoaderHook.java @@ -14,11 +14,10 @@ import org.eclipse.osgi.internal.loader.ModuleClassLoader; import net.sf.jremoterun.utilities.JrrClassUtils; -import sun.reflect.Reflection; public class MyEclipseClassLoaderHook extends ClassLoaderHook { - private static final Logger log = Logger.getLogger(Reflection.getCallerClass(1).getName()); + private static final Logger log = Logger.getLogger(JrrClassUtils.getCurrentClass().getName()); public static MyEclipseClassLoaderHook myEclipseClassLoaderHook2; @@ -29,7 +28,7 @@ public class MyEclipseClassLoaderHook extends ClassLoaderHook { public boolean isMyModule(ModuleClassLoader classLoader) { String symbolicName = classLoader.getBundle().getSymbolicName(); if (myModules.contains(symbolicName)) { - log.info("my module search class"); + // log.info("my module search class"); return true; } return false; @@ -45,7 +44,7 @@ public Class postFindClass(String name, ModuleClassLoader classLoader) throws if (name.startsWith(entry.getKey())) { BundleLoader bundleLoader = entry.getValue(); Class findClass = bundleLoader.findClass(name); - log.info("class found"); + log.info("class found : "+name); return findClass; } } diff --git a/src-eclipse-showcmd/nik/git/forcepush/SetEclipseLogHandler.java b/src-eclipse-showcmd/nik/git/forcepush/SetEclipseLogHandler.java deleted file mode 100644 index 66dfebde..00000000 --- a/src-eclipse-showcmd/nik/git/forcepush/SetEclipseLogHandler.java +++ /dev/null @@ -1,38 +0,0 @@ -package nik.git.forcepush; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.eclipse.ui.application.WorkbenchAdvisor; -import org.eclipse.ui.internal.Workbench; -import org.eclipse.ui.internal.ide.IDEWorkbenchErrorHandler; - -import net.sf.jremoterun.utilities.JrrClassUtils; -import net.sf.jremoterun.utilities.JrrUtilities3; -import nik.git.forcepush.jrr.JrrCommonEclipseBean; - -public class SetEclipseLogHandler { - - private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - - public static void setLogHandler() { - try { - WorkbenchAdvisor workbenchErrorHandler = (WorkbenchAdvisor) JrrClassUtils - .getFieldValue(Workbench.getInstance(), "advisor"); - IDEWorkbenchErrorHandler ideWorkbenchErrorHandler = JrrCommonEclipseBean.bean.getIdeWorkbenchErrorHandler(); - if (ideWorkbenchErrorHandler == null) { - ideWorkbenchErrorHandler = (IDEWorkbenchErrorHandler) workbenchErrorHandler.getWorkbenchErrorHandler(); - JrrCommonEclipseBean.bean.setIdeWorkbenchErrorHandler(ideWorkbenchErrorHandler); - } - MyIDEWorkbenchErrorHandler errorHandler = new MyIDEWorkbenchErrorHandler(); - errorHandler.handler = ideWorkbenchErrorHandler; - JrrClassUtils.setFieldValue(workbenchErrorHandler, "ideWorkbenchErrorHandler", errorHandler); - JrrClassUtils.ignoreClassesForCurrentClass.add(MyIDEWorkbenchErrorHandler.class.getName()); - } catch (Exception e) { - JrrUtilities3.showException("eclipse 8 start 123", e); - e.printStackTrace(); - log.log(Level.SEVERE, null, e); - } - } - -} diff --git a/src-eclipse-showcmd/nik/git/forcepush/jrr/PushForceImpl2.java b/src-eclipse-showcmd/nik/git/forcepush/jrr/PushForceImpl2.java index 9a5fc148..f584f566 100644 --- a/src-eclipse-showcmd/nik/git/forcepush/jrr/PushForceImpl2.java +++ b/src-eclipse-showcmd/nik/git/forcepush/jrr/PushForceImpl2.java @@ -22,12 +22,20 @@ import org.eclipse.ui.IWorkbenchPart; import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.JrrUtilities; +import net.sf.jremoterun.utilities.nonjdk.git.GitProgressMonitorJrr; +import net.sf.jremoterun.utilities.nonjdk.git.GitRemoteFind; +import net.sf.jremoterun.utilities.nonjdk.git.GitRepoUtils; public class PushForceImpl2 implements IObjectActionDelegate { private static final java.util.logging.Logger LOG = java.util.logging.Logger .getLogger(JrrClassUtils.getCurrentClass().getName()); + public static String myUserName = System.getProperty("user.name"); + public static boolean needSetMyRemote = true; + public static GitProgressMonitorJrr progressMonitor = new GitProgressMonitorJrr(); + private IWorkbenchPart activePart; private File selectedRepositoryLocation; @@ -55,6 +63,7 @@ public void run(IAction action) { forceFush(selectedRepositoryLocation); } catch (Exception e) { LOG.log(Level.SEVERE, null, e); + JrrUtilities.showException("Push force failed", e); } } @@ -65,6 +74,10 @@ private static void forceFush(File file) throws Exception { // create.subcommand; org.eclipse.jgit.api.Git git = Git.open(file); PushCommand push = git.push(); + push.setProgressMonitor(progressMonitor); + if(needSetMyRemote) { + push.setRemote(findMyRemote(file)); + } push.setForce(true); Iterable callResult = push.call(); StringBuilder sb = new StringBuilder(); @@ -113,6 +126,20 @@ private static void forceFush(File file) throws Exception { // test2 MessageDialog.openWarning(null, "Git push force", file.getAbsolutePath() + " \n" + sb); } + + public static String findMyRemote(File file) { + GitRepoUtils gitRepoUtils = new GitRepoUtils(file); + GitRemoteFind gitRemoteFind = new GitRemoteFind() { + + @Override + public boolean isRepoGood(String uri) { + return uri.startsWith(myUserName); + } + + }; + String remote = gitRemoteFind.detectRemote(gitRepoUtils); + return remote; + } private void updateActionEnablement(IAction action) { action.setEnabled(activePart != null && selectedRepositoryLocation != null); diff --git a/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/EclipseLunaClasspathAdd.groovy b/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/EclipseLunaClasspathAdd.groovy index 663886b6..98697785 100644 --- a/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/EclipseLunaClasspathAdd.groovy +++ b/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/EclipseLunaClasspathAdd.groovy @@ -9,6 +9,7 @@ import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunner import net.sf.jremoterun.utilities.groovystarter.st.SetConsoleOut2 import org.codehaus.groovy.control.CompilationFailedException +import net.sf.jremoterun.utilities.groovystarter.JrrStarterVariables; import org.eclipse.osgi.internal.debug.Debug import org.eclipse.osgi.internal.framework.EquinoxContainer import org.eclipse.osgi.internal.loader.EquinoxClassLoader @@ -24,7 +25,9 @@ public class EclipseLunaClasspathAdd { public static volatile boolean inited = false public static volatile Thread initializerThread; static final Object lock1 = new Object() - public static org.eclipse.osgi.internal.loader.EquinoxClassLoader clP; + public static org.eclipse.osgi.internal.loader.EquinoxClassLoader clP; + public static List debugFlags = []; + public static File eclipseInitScriptDebug; private static final Logger log = Logger.getLogger(JrrClassUtils.getCurrentClass().getName()); @@ -82,9 +85,12 @@ public class EclipseLunaClasspathAdd { } public static void initImpl() throws Exception { + debugFlags.add(1); initializerThread = Thread.currentThread(); SetConsoleOut2.setConsoleOutIfNotInited(); + debugFlags.add(2); initImpl2(); + debugFlags.add(3); } static void enableParalellLoading(boolean enable) { @@ -92,31 +98,63 @@ public class EclipseLunaClasspathAdd { } public static void initImpl2() throws Exception { + debugFlags.add(21); log.info("starting added cutom classed"); log.info("thread details : ${initializerThread.name} ${initializerThread.id}"); classpathManager = findClasspathManager(); + debugFlags.add(22); enableParalellLoading(false); - + debugFlags.add(23); // al.add(classpathEntry); ClasspathEntry[] classpathEntries = (ClasspathEntry[]) JrrClassUtils.getFieldValue(classpathManager, "entries"); - al = new ArrayList(Arrays.asList(classpathEntries)); + debugFlags.add(24); + al = new ArrayList(Arrays.asList(classpathEntries)); // classpathManager.addClassPathEntry(al, clName, classpathManager, // null); // FileInputStream fis=new FileInputStream(file); addCl = new EclipseInitAddFilesToClassLoaderGroovy(); + debugFlags.add(26); // addCl.addFromGroovyFile(EclipseSettings.fileWithCLassPath2); runScriptInUserDir(); + debugFlags.add(27); runCustom(); + debugFlags.add(28); // addCl.addFromGroovyFile(EclipseSettings.fileWithCLassPath4); log.info("trying adding : " + addCl.getAddedFiles2().size()); JrrClassUtils.setFieldValue(classpathManager, "entries", al.toArray(classpathEntries)); + debugFlags.add(29); log.info("classes added fine"); } static void runScriptInUserDir() throws CompilationFailedException, IOException { + if(JrrStarterVariables.filesDir==null){ + debugFlags.add(1); + log.info "files dir is null" + JrrUtilities.showException("files dir is null",new Exception("files dir is null")); + }else{ + eclipseInitScriptDebug = new File(JrrStarterVariables.filesDir,JrrEclipseStartupSettings.eclipseInitGroovyScriptName); + if(eclipseInitScriptDebug.exists()){ + debugFlags.add 2; + if(JrrStarterVariables.classesDir!=null){ + debugFlags.add 3; + addCl.addF JrrStarterVariables.classesDir + } + log.info("running ${eclipseInitScriptDebug} .."); + Script parse = GroovyMethodRunner.groovyScriptRunner.groovyShell.parse(eclipseInitScriptDebug) + parse.run() + log.info("finished ${eclipseInitScriptDebug}"); + }else{ + log.info "file not exist : ${eclipseInitScriptDebug}" + debugFlags.add 4; + JrrUtilities.showException("file not exist : ${eclipseInitScriptDebug}",new Exception("file not exist : ${eclipseInitScriptDebug}")); + } + debugFlags.add 5; + } + + File userHome = new File(System.getProperty("user.home")); if (userHome.exists()) { File scriptInUserDir = new File(userHome, "jrr/configs/eclipse.groovy"); diff --git a/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/JrrEclipseStartupSettings.java b/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/JrrEclipseStartupSettings.java new file mode 100644 index 00000000..cef65312 --- /dev/null +++ b/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/JrrEclipseStartupSettings.java @@ -0,0 +1,6 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse; + +public class JrrEclipseStartupSettings { + + public static String eclipseInitGroovyScriptName = "eclipse.groovy"; +} diff --git a/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/MyStartup.java b/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/MyStartup.java index 6b23fbea..8e861ebb 100644 --- a/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/MyStartup.java +++ b/src-eclipse-starter/net/sf/jremoterun/utilities/nonjdk/eclipse/MyStartup.java @@ -11,7 +11,6 @@ import net.sf.jremoterun.utilities.JrrUtilities; import net.sf.jremoterun.utilities.JrrUtilities3; -import sun.reflect.Reflection; @CompileStatic public class MyStartup extends AbstractUIPlugin implements IStartup { diff --git a/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/SvnAdapterManagerJrr.java b/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/SvnAdapterManagerJrr.java new file mode 100644 index 00000000..27b9a69e --- /dev/null +++ b/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/SvnAdapterManagerJrr.java @@ -0,0 +1,53 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.svn; + +import java.util.Map; +import java.util.logging.Logger; + +import org.tigris.subversion.clientadapter.Activator; +import org.tigris.subversion.clientadapter.AdapterManager; + +import net.sf.jremoterun.utilities.JrrClassUtils; + +// Remove native impl from Preferences -> team -> SVN -> svn interface +public class SvnAdapterManagerJrr extends AdapterManager{ + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static String javahlS = "javahl"; + public static String svnkit = "svnkit"; + + public static volatile boolean inited = false; + public static AdapterManager adapterManagerOrigin; + + public static void removeNativeSvnImpl() throws Exception { + if(inited) { + log.info("already inited"); + }else { + inited = true; + removeNativeSvnImpl2(); + } + } + + public static void removeNativeSvnImpl2() throws Exception { + Activator activator = Activator.getDefault(); + activator.getAllClientWrappers(); + adapterManagerOrigin = (AdapterManager) JrrClassUtils.getFieldValue(activator, "adapterManager"); + JrrClassUtils.setFieldValue(activator, "adapterManager",new SvnAdapterManagerJrr()); + activator.getAllClientWrappers(); + Map javahl2 = adapterManagerOrigin.getClientWrappers(); + log.info("current svn adaptors before remove : "+javahl2.keySet()); + javahl2.remove(javahlS); + log.info("current svn adaptors after remove : "+javahl2.keySet()); + } + + + @Override + public synchronized Map getClientWrappers() { + Map javahl2 = super.getClientWrappers(); + + log.info("current svn adaptors : "+javahl2.keySet()); + javahl2.remove( SvnAdapterManagerJrr.javahlS); + return javahl2; + + } +} diff --git a/src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/SvnUpdater2.java b/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/SvnUpdater2.java similarity index 100% rename from src-eclipse-showcmd/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/SvnUpdater2.java rename to src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/SvnUpdater2.java diff --git a/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/ActivatorJrr.java b/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/ActivatorJrr.java new file mode 100644 index 00000000..dd40b8ba --- /dev/null +++ b/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/ActivatorJrr.java @@ -0,0 +1,59 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.svn.password; + +import org.tigris.subversion.clientadapter.ISVNClientWrapper; +import org.tigris.subversion.svnclientadapter.ISVNClientAdapter; +import org.tmatesoft.svn.core.javahl17.SVNClientImpl; + +// org.tigris.subversion.clientadapter.svnkit.Activator +public class ActivatorJrr implements ISVNClientWrapper { + public static final String PLUGIN_ID = "org.tigris.subversion.clientadapter.svnkit"; + public static final String PT_SVNCONNECTORFACTORY = "svnconnectorfactory"; +// private static ActivatorJrr plugin; + private String displayName; + private String version; + + public ISVNClientAdapter getAdapter() { + return this.isAvailable() ? new SvnKitClientAdapterJrr() : null; + } + + public String getAdapterID() { + return "svnkit"; + } + + public String getVersionString() { + return this.getVersionSynchronized(); + } + + private synchronized String getVersionSynchronized() { + if (this.version == null) { + if (this.isAvailable()) { + SVNClientImpl adapter = new SvnClientJrr(); + this.version = adapter.getVersion().toString(); + } else { + this.version = "Not Available"; + } + } + + return this.version; + } + + public boolean isAvailable() { + return true; + } + + public void setDisplayName(String string) { + this.displayName = string; + } + + public String getDisplayName() { + return this.displayName + " " + this.getVersionString(); + } + + public String getLoadErrors() { + return this.isAvailable() + ? "" + : "Class org.tmatesoft.svn.core.javahl17.SVNClientImpl not found.\nInstall the SVNKit plug-in from http://www.svnkit.com/"; + } + + +} \ No newline at end of file diff --git a/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/SvnClientJrr.java b/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/SvnClientJrr.java new file mode 100644 index 00000000..84bf29f6 --- /dev/null +++ b/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/SvnClientJrr.java @@ -0,0 +1,79 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.svn.password; + +import java.util.logging.Logger; + +import org.apache.subversion.javahl.ClientException; +import org.apache.subversion.javahl.callback.ConflictResolverCallback; +import org.apache.subversion.javahl.callback.UserPasswordCallback; +import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; +import org.tmatesoft.svn.core.internal.wc.ISVNAuthenticationStorage; +import org.tmatesoft.svn.core.javahl17.SVNClientImpl; +import org.tmatesoft.svn.core.wc.SVNWCUtil; + +import javassist.CtClass; +import javassist.CtMethod; +import javassist.NotFoundException; +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.javassist.JrrJavassistUtils; + +public class SvnClientJrr extends SVNClientImpl { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + + + + @Override + public void password(String password) { + super.password(password); + //call setMyAuthenticationManager + } + + @Override + public void username(String username) { + super.username(username); + //call setMyAuthenticationManager + } + + + @Override + public void setPrompt(UserPasswordCallback prompt) { + super.setPrompt(prompt); + //call setMyAuthenticationManager + } + + + @Override + public void setConflictResolver(ConflictResolverCallback callback) { + super.setConflictResolver(callback); + //call setMyAuthenticationManager + } + + @Override + public void setClientCredentialsStorage(ISVNAuthenticationStorage storage) { + super.setClientCredentialsStorage(storage); + //call setMyAuthenticationManager + } + + + @Override + public void setConfigDirectory(String configDir) throws ClientException { + super.setConfigDirectory(configDir); + //call setMyAuthenticationManager + } + + + public void setMyAuthenticationManager(String userName,String password) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException{ + ISVNAuthenticationManager defaultAuthenticationManager = SVNWCUtil.createDefaultAuthenticationManager(null, userName, password.toCharArray(),null,null,false); + JrrClassUtils.setFieldValue(this, "authenticationManager", defaultAuthenticationManager); + } + + static void setCustomImpl() throws Exception { + Class clazz = SVNClientImpl.class; + CtClass ctClass = JrrJavassistUtils.getClassFromDefaultPool(clazz); + CtMethod method1 = JrrJavassistUtils.findMethod(clazz, ctClass, "newInstance",0); + method1.setBody("return new SvnClientJrr()"); + + } +} diff --git a/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/SvnKitClientAdapterJrr.java b/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/SvnKitClientAdapterJrr.java new file mode 100644 index 00000000..d9a33615 --- /dev/null +++ b/src-eclipse-svn/net/sf/jremoterun/utilities/nonjdk/eclipse/svn/password/SvnKitClientAdapterJrr.java @@ -0,0 +1,83 @@ +package net.sf.jremoterun.utilities.nonjdk.eclipse.svn.password; + +import java.io.File; +import java.util.logging.Logger; +import net.sf.jremoterun.utilities.JrrClassUtils; +import org.tigris.subversion.svnclientadapter.ISVNPromptUserPassword; +import org.tigris.subversion.svnclientadapter.ISVNStatus; +import org.tigris.subversion.svnclientadapter.SVNClientException; +import org.tigris.subversion.svnclientadapter.SVNStatusUnversioned; +import org.tigris.subversion.svnclientadapter.javahl.AbstractJhlClientAdapter; +import org.tigris.subversion.svnclientadapter.javahl.JhlNotificationHandler; +import org.tigris.subversion.svnclientadapter.javahl.JhlProgressListener; +import org.tigris.subversion.svnclientadapter.javahl.AbstractJhlClientAdapter.DefaultPromptUserPassword; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.io.SVNRepositoryFactory; + +// org.tigris.subversion.clientadapter.svnkit.Activator +public class SvnKitClientAdapterJrr extends AbstractJhlClientAdapter{ + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public SvnKitClientAdapterJrr() { + this.svnClient = new SvnClientJrr(); + this.notificationHandler = new JhlNotificationHandler(); + this.progressListener = new JhlProgressListener(); + this.svnClient.notification2(this.notificationHandler); + this.svnClient.setPrompt(new DefaultPromptUserPassword()); + this.svnClient.setProgressCallback(this.progressListener); + } + + public boolean isThreadsafe() { + return false; + } + + public void createRepository(File path, String repositoryType) throws SVNClientException { + if ("bdb".equalsIgnoreCase(repositoryType)) { + throw new SVNClientException("SVNKit only supports fsfs repository type."); + } else { + try { + boolean force = false; + boolean enableRevisionProperties = false; + SVNRepositoryFactory.createLocalRepository(path, enableRevisionProperties, force); + } catch (SVNException var5) { + this.notificationHandler.logException(var5); + throw new SVNClientException(var5); + } + } + } + + public void addPasswordCallback(ISVNPromptUserPassword callback) { +// if (callback != null) { +// SvnKitPromptUserPassword prompt = new SvnKitPromptUserPassword(callback); +// this.setPromptUserPassword(prompt); +// } + + } + + public boolean statusReturnsRemoteInfo() { + return true; + } + + public boolean canCommitAcrossWC() { + return false; + } + + public ISVNStatus[] getStatus(File path, boolean descend, boolean getAll, boolean contactServer, + boolean ignoreExternals) throws SVNClientException { + ISVNStatus[] statuses = super.getStatus(path, descend, getAll, contactServer, ignoreExternals); + if (statuses.length == 0) { + if (getAll) { + return new ISVNStatus[]{new SVNStatusUnversioned(path)}; + } else { + ISVNStatus[] reCheckStatuses = super.getStatus(path, false, true, false, true); + return reCheckStatuses.length == 0 + ? new ISVNStatus[]{new SVNStatusUnversioned(path)} + : new ISVNStatus[0]; + } + } else { + return statuses; + } + } + +} diff --git a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/IfFrameworkResourceDirs.groovy b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/IfFrameworkResourceDirs.groovy index 4b8d28ef..3b80263b 100644 --- a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/IfFrameworkResourceDirs.groovy +++ b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/IfFrameworkResourceDirs.groovy @@ -3,9 +3,11 @@ package net.sf.jremoterun.utilities.nonjdk import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.ToFileRef2 import net.sf.jremoterun.utilities.classpath.ToFileRefSelf +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef @CompileStatic -enum IfFrameworkResourceDirs implements ToFileRefSelf{ +enum IfFrameworkResourceDirs implements ToFileRefSelf, ChildFileLazy, ToFileRef2{ resources_groovy, resources, @@ -28,6 +30,10 @@ enum IfFrameworkResourceDirs implements ToFileRefSelf{ return InfocationFrameworkStructure.ifDir.child(this.dirName) } + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this, child); + } public static List all= values().toList() diff --git a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/IfFrameworkSrcDirs.groovy b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/IfFrameworkSrcDirs.groovy index a6d52304..1bb1d87b 100644 --- a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/IfFrameworkSrcDirs.groovy +++ b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/IfFrameworkSrcDirs.groovy @@ -3,26 +3,47 @@ package net.sf.jremoterun.utilities.nonjdk import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.classpath.ToFileRef2 import net.sf.jremoterun.utilities.classpath.ToFileRefSelf +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ChildFileLazy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef @CompileStatic -enum IfFrameworkSrcDirs implements ToFileRefSelf{ +enum IfFrameworkSrcDirs implements ToFileRefSelf, ChildFileLazy, ToFileRef2{ src_common, src, + src_timmoson, src_groovycompiler, src_idw, src_jedi, src_logger_ext_methods, src_rsta_core, src_rsta_runner, + src_jsshext, + src_archiver, src_frameworkloader, - src_idea, src_idea2,src_idea_launcher,src_idea_launcher2, + src_idea, src_idea2,src_idea_launcher,src_idea_launcher2, src_idea_github, - src_eclipse_starter, src_eclipse_showcmd, + src_eclipse_starter, src_eclipse_showcmd,src_eclipse_svn, src_helfyutils, + + src_maven, + src_maven_http, + src_maven_plugin_ext, + src_maven_launcher, + src_java8, + //src_java11, + + src_githubutils, + src_gitlabutils, + + src_netbeans, + + src_idea_audio, + src_compiler_jdk, + ; String dirName; @@ -39,11 +60,21 @@ enum IfFrameworkSrcDirs implements ToFileRefSelf{ return InfocationFrameworkStructure.ifDir.child(this.dirName) } - public static List dir2 = [src_common, src, src_groovycompiler, src_idw,src_frameworkloader, - src_jedi, src_logger_ext_methods, src_rsta_core, src_rsta_runner,] - public static List idea= [src_idea, src_idea2,] - public static List eclipse= [src_eclipse_starter, src_eclipse_showcmd,] + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this, child); + } + + + + public static List dir2 = [src_common, src, src_groovycompiler, src_idw,src_frameworkloader,src_jsshext, + src_jedi, src_logger_ext_methods, src_rsta_core, src_rsta_runner,src_timmoson, + src_archiver, + src_maven_launcher,] + + public static List idea= [src_idea, src_idea2,src_idea_github,] + public static List eclipse= [src_eclipse_starter, src_eclipse_showcmd, src_eclipse_svn,] public static List all= values().toList() diff --git a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/InfocationFrameworkAndGitAdder.groovy b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/InfocationFrameworkAndGitAdder.groovy index 1af957f0..72be6fbc 100644 --- a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/InfocationFrameworkAndGitAdder.groovy +++ b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/InfocationFrameworkAndGitAdder.groovy @@ -15,11 +15,12 @@ class InfocationFrameworkAndGitAdder extends InjectedCode { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - static ClRef gitAdderSupport = new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ClassPathInit3') + public static ClRef gitAdderSupport = new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ClassPathInit3') @Override Object get(Object o) { + JavaVersionChecker.checkJavaVersion() List list = (List) o; if (list == null) { throw new IllegalArgumentException("need set adder and InfocationFramework base dir") @@ -28,23 +29,42 @@ class InfocationFrameworkAndGitAdder extends InjectedCode { throw new IllegalArgumentException("need set adder and InfocationFramework base dir, but got : ${list}") } AddFilesToClassLoaderCommon adder = list[0] as AddFilesToClassLoaderCommon; + File ifDir = list[1] as File + File gitDir = list[2] as File + addStuff(adder,ifDir,gitDir) + return null; + } + + static void addStuffGit(AddFilesToClassLoaderCommon adder,File gitDir ){ if (adder == null) { throw new IllegalArgumentException("adder is null") } - File ifDir = list[1] as File + + + if (gitDir == null) { + throw new IllegalArgumentException("Git dir is null") + } + assert gitDir.exists() + RunnableWithParamsFactory.fromClass4(gitAdderSupport,[adder,gitDir]) + } + + static void addStuff(AddFilesToClassLoaderCommon adder,File ifDir,File gitDir ){ + if (adder == null) { + throw new IllegalArgumentException("adder is null") + } + if (ifDir == null) { throw new IllegalArgumentException("InfocationFramework base dir is null") } - File gitDir = list[2] as File + if (gitDir == null) { throw new IllegalArgumentException("Git dir is null") } assert gitDir.exists() InfocationFrameworkStructure.addRefs(adder,ifDir) - RunnableWithParamsFactory.fromClass4(gitAdderSupport,[adder,gitDir]) - return null; + addStuffGit(adder,gitDir) } diff --git a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/InfocationFrameworkStructure.groovy b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/InfocationFrameworkStructure.groovy index 874bf3c9..5b1e5ddb 100644 --- a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/InfocationFrameworkStructure.groovy +++ b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/InfocationFrameworkStructure.groovy @@ -40,6 +40,7 @@ class InfocationFrameworkStructure extends InjectedCode { @Override Object get(Object o) { + JavaVersionChecker.checkJavaVersion() List list = (List) o; if (list == null) { throw new IllegalArgumentException("need set adder and InfocationFramework base dir") diff --git a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/JavaVersionChecker.groovy b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/JavaVersionChecker.groovy new file mode 100644 index 00000000..bb31c0cd --- /dev/null +++ b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/JavaVersionChecker.groovy @@ -0,0 +1,31 @@ +package net.sf.jremoterun.utilities.nonjdk + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import java.util.logging.Logger; + +@CompileStatic +class JavaVersionChecker { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public static boolean javaVersionChecked = false + public static String goodJavaVersion = '1.8' + + static void checkJavaVersion() { + if (!javaVersionChecked) { + javaVersionChecked = true; + checkJavaVersionImpl(); + } + } + + static boolean checkJavaVersionImpl() { + String java_version = System.getProperty("java.specification.version") + if (java_version != goodJavaVersion) { + log.severe "bad java version : ${java_version}, needed : ${goodJavaVersion}" + return false + } + return true + } + +} diff --git a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ChildFileLazy.groovy b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ChildFileLazy.groovy new file mode 100644 index 00000000..9007f35a --- /dev/null +++ b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/ChildFileLazy.groovy @@ -0,0 +1,15 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.helpers + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ToFileRef2; + +import java.util.logging.Logger; + +@CompileStatic +interface ChildFileLazy { + + FileChildLazyRef childL(String child); + + +} diff --git a/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/FileChildLazyRef.groovy b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/FileChildLazyRef.groovy new file mode 100644 index 00000000..aacf8eb3 --- /dev/null +++ b/src-frameworkloader/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/FileChildLazyRef.groovy @@ -0,0 +1,44 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.helpers + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.CustomObjectHandler +import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.classpath.ToFileRef2; + +import java.util.logging.Logger; + +@CompileStatic +class FileChildLazyRef implements ToFileRef2 , ChildFileLazy{ + //private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ToFileRef2 parentRef; + String child; + + FileChildLazyRef(ToFileRef2 parentRef, String child) { + this.parentRef = parentRef + this.child = child + } + + @Override + File resolveToFile() { + File parentFile = parentRef.resolveToFile() + return new File(parentFile,child); +// CustomObjectHandler handler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler +// if(handler==null){ +// throw new IllegalStateException("customObjectHandler was not set") +// } +// return handler.resolveToFile(this) + } + + @Override + FileChildLazyRef childL(String child) { + return new FileChildLazyRef(this,child) +// return null; + } + + @Override + String toString() { + return "${parentRef} .child( ${child} )" + } +} diff --git a/src-githubutils/net/sf/jremoterun/utilities/nonjdk/git/hub/GitHubUtils.groovy b/src-githubutils/net/sf/jremoterun/utilities/nonjdk/git/hub/GitHubUtils.groovy new file mode 100644 index 00000000..87c22f1b --- /dev/null +++ b/src-githubutils/net/sf/jremoterun/utilities/nonjdk/git/hub/GitHubUtils.groovy @@ -0,0 +1,60 @@ +package net.sf.jremoterun.utilities.nonjdk.git.hub + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.git.GitRepoUtils +import net.sf.jremoterun.utilities.nonjdk.git.GitSpec +import org.eclipse.egit.github.core.Repository +import org.eclipse.egit.github.core.client.GitHubClient +import org.eclipse.egit.github.core.service.RepositoryService; + +import java.util.logging.Logger; + +@CompileStatic +abstract class GitHubUtils { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public GitHubClient gitHubClient; + public RepositoryService rs; + public List ignoreRepos = []; + + GitHubUtils(GitHubClient gitHubClient) { + this.gitHubClient = gitHubClient + // new GitHubClient(''host).setCred(user,pass) + rs = new RepositoryService(gitHubClient) + } + + void cloneOrg(String orgName) { + List repositories = rs.getOrgRepositories(orgName); + log.info "repos size : ${repositories.size()}" + if (repositories.size() <= 0) { + throw new Exception("no repo found for ${orgName}") + } + + repositories.each { + try { + if (canCloneRepo(it)) { + cloneRepo(it) + } else { + log.info "ignore repo ${it.getName()}" + } + } catch (Exception e) { + log.info "failed clone repo ${it.getName()} ${e}" + throw e + } + } + } + + boolean canCloneRepo(Repository repo) { + return !(ignoreRepos.contains(repo.getName())); + } + + //repository.getName() + abstract GitSpec createGitSpec(Repository repository) + + void cloneRepo(Repository repository) { + GitSpec gitSpec = createGitSpec(repository) + GitRepoUtils.updateGitRepo2(gitSpec) + } + +} diff --git a/src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitLabUtils.groovy b/src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitLabUtils.groovy new file mode 100644 index 00000000..f3ae076c --- /dev/null +++ b/src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitLabUtils.groovy @@ -0,0 +1,104 @@ +package net.sf.jremoterun.utilities.nonjdk.git.lab + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.git.GitRepoUtils +import net.sf.jremoterun.utilities.nonjdk.git.GitSpec +import org.gitlab4j.api.GitLabApi +import org.gitlab4j.api.GitLabApiClient +import org.gitlab4j.api.Pager +import org.gitlab4j.api.models.Project +import org.gitlab4j.api.models.ProjectFilter +import org.glassfish.jersey.client.ClientConfig +import org.glassfish.jersey.logging.LoggingFeature + +import java.util.logging.Level +import java.util.logging.Logger + +@CompileStatic +class GitLabUtils { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public GitLabApi gitLabClient; + public List ignoreRepos = []; + public int maxProjectsOnPage = 30; + public boolean cloneAsSsh = true; + + GitLabUtils(GitLabApi gitLabClient) { + this.gitLabClient = gitLabClient + } + + List getChildProjects1(String orgName, int maxProjectsOnPage1) { + return getChildProjects(gitLabClient, orgName, maxProjectsOnPage1) + } + + static List getChildProjects(GitLabApi gitLabClient1, String orgName, int maxProjectsOnPage1) { + ProjectFilter pf = new ProjectFilter() + pf.withSearchNamespaces(true); + pf.withSearch(orgName); + Pager projects = gitLabClient1.getProjectApi().getProjects(pf, maxProjectsOnPage1); + int totalItems1 = projects.getTotalItems() + if (totalItems1 > maxProjectsOnPage1) { + throw new Exception("got too many projects : ${totalItems1}") + } + List next1 = projects.next() + if (next1.size() <= 0) { + throw new Exception("no repo found for ${orgName}") + } + return next1; + } + + void cloneOrg(String orgName) { + cloneOrg(orgName, maxProjectsOnPage) + } + + void cloneOrg(String orgName, int maxProjectsOnPage1) { + List current = getChildProjects1(orgName, maxProjectsOnPage1) + current.each { + try { + if (canCloneRepo(it)) { + log.info "clonning ${it.getNameWithNamespace()}" + cloneRepo(it) + } else { + log.info "ignore repo ${it.getName()}" + } + } catch (Exception e) { + log.info "failed clone repo ${it.getName()} ${e}" + throw e + } + } + } + + boolean canCloneRepo(Project repo) { + return !(ignoreRepos.contains(repo.getName())); + } + + GitSpec createGitSpec(Project repository) { + if (cloneAsSsh) { + return new GitSpec(repository.getSshUrlToRepo()) + } + return new GitSpec(repository.getHttpUrlToRepo()) + } + + void cloneRepo(Project repository) { + GitSpec gitSpec = createGitSpec(repository); + GitRepoUtils.updateGitRepo2(gitSpec); + } + + + static ClientConfig getClientConfig(GitLabApi gitLabApi) { + GitLabApiClient gitLabApiClient = JrrClassUtils.getFieldValue(gitLabApi, 'apiClient') as GitLabApiClient + ClientConfig clientConfig = JrrClassUtils.getFieldValue(gitLabApiClient, 'clientConfig') as ClientConfig + return clientConfig + } + + static void addLogging(GitLabApi gitLabApi) { + ClientConfig clientConfig = getClientConfig(gitLabApi) + LoggingFeature loggingFeature = new LoggingFeature(log, Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 1000); + clientConfig.register(loggingFeature) + } + +} + + + diff --git a/src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitlabMrMonitor.groovy b/src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitlabMrMonitor.groovy new file mode 100644 index 00000000..fe3f53d6 --- /dev/null +++ b/src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitlabMrMonitor.groovy @@ -0,0 +1,171 @@ +package net.sf.jremoterun.utilities.nonjdk.git.lab + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.timer.CronTimer +import org.gitlab4j.api.Constants +import org.gitlab4j.api.GitLabApi +import org.gitlab4j.api.MergeRequestApi +import org.gitlab4j.api.models.Discussion +import org.gitlab4j.api.models.MergeRequest +import org.gitlab4j.api.models.MergeRequestFilter +import org.gitlab4j.api.models.Note +import org.gitlab4j.api.models.User + +import java.util.concurrent.ConcurrentHashMap +import java.util.logging.Logger + +@CompileStatic +abstract class GitlabMrMonitor { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public GitLabApi gitLabApi; +// public Map> maps = [:] +// public Map> project2MrMap = new ConcurrentHashMap<>() + // lock evry time when query : to run 1 query per time + public final Object lock = new Object() +// public int runBigQueryEvery = 10; + public int bigQueryEveryCountDown = 0; + //public boolean doRun = true; + //public long sleepTimeInSec = 60; + public long queryTimeToExecute = -1 + public Map, MergeRequest> mapObject = new HashMap<>() + public CronTimer cronTimer = new CronTimer({ runnn2() }) + public Date lastTimeToCheck + public volatile User meUser; + + + GitlabMrMonitor(GitLabApi gitLabApi) { + this.gitLabApi = gitLabApi + } + + void startEveryMinute() { + start('1 * * ? * *') + } + + void start(String cronExpression) { + cronTimer.setCronExpressions(cronExpression) + cronTimer.start() + } + + void runnn2() { + try { + runnn2Impl() + } catch (Throwable e) { + log.info "got exception ${e}" + onException(e) + } + } + + void runnn2Impl() { +// if (bigQueryEveryCountDown == 0) { + doBigQuery() +// bigQueryEveryCountDown = runBigQueryEvery; +// } else { +// bigQueryEveryCountDown--; +//// runSmallQuery() +// } + } + + void doBigQuery() { + synchronized (lock) { + if (meUser == null) { + meUser = gitLabApi.getUserApi().getCurrentUser() + } + MergeRequestApi mergeRequestApi = gitLabApi.getMergeRequestApi() + MergeRequestFilter filter = new MergeRequestFilter(); + Date lastTimeToCheck2 = new Date() + filter.withScope(Constants.MergeRequestScope.CREATED_BY_ME) + boolean fullQuery = lastTimeToCheck == null + if (fullQuery) { + filter.withState(Constants.MergeRequestState.OPENED) + } else { + filter.updatedAfter = lastTimeToCheck + } + lastTimeToCheck = new Date() +// filter.setSimpleView(true) + List mergeRequests = mergeRequestApi.getMergeRequests(filter) + List aaa = [] + mergeRequests.each { + gotMergeRequest(it) + aaa.add(it.getIid()) + }; + log.info "got mr = ${aaa}" + mergeRequests.each { + List key = [it.projectId, it.iid] + mapObject.put(key, it) + } + lastTimeToCheck = lastTimeToCheck2 + queryTimeToExecute = System.currentTimeMillis() - lastTimeToCheck2.getTime(); + } + } + + void gotMergeRequest(MergeRequest mr) { + synchronized (lock) { + + List key = [mr.projectId, mr.iid] + MergeRequest mrBefore = mapObject.get(key) + if (mrBefore == null) { + onMrAdded(mr) + } else { + if('merged'.equalsIgnoreCase(mr.getState())){ + onMerged(mr); + }else { + onMrUpdated(mrBefore, mr) + } + } + } + + } + + + abstract void onException(Throwable e); + + void onMrUpdated(MergeRequest mrOld, MergeRequest mrNew) { + if (mrOld.getUserNotesCount() == mrNew.getUserNotesCount()) { + log.info "updated dummy ${mrNew.getUserNotesCount()}" + onOtherUpdates(mrOld, mrNew) + } else { + onMrUpdatedUserNotes(mrOld, mrNew) + } + } + + void onMrUpdatedUserNotes(MergeRequest mrOld, MergeRequest mrNew) { + List discussions = gitLabApi.getDiscussionsApi().getMergeRequestDiscussions(mrNew.getProjectId(), mrNew.iid) + int diff = mrNew.getUserNotesCount() - mrOld.getUserNotesCount() + if (diff > 0) { + int size = discussions.size() + List new12 = discussions.subList(size - diff, size) + new12 = new12.findAll { isShowDiscussion(it) } + if (new12.size() > 0) { + onNewComments(mrNew, new12) + } else { + log.info "skip my comments" + } + } else { + log.info "comment count diff ${diff}" + } + } + + boolean isShowDiscussion(Discussion discussion) { + List notes = discussion.getNotes() + Note note1 = notes.find { isShowNote(it) } + return note1 != null + } + + boolean isShowNote(Note note) { + return note.getAuthor() != null && note.getAuthor().getId() != meUser.getId() + } + + + abstract void onOtherUpdates(MergeRequest mrOld, MergeRequest mrNew) + + abstract void onNewComments(MergeRequest mr, List comment) + + abstract void onMrAdded(MergeRequest mr); + + //abstract void onMrRemoved(MergeRequest mr); + + abstract void onMerged(MergeRequest mr); + +} diff --git a/src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitlabPipelineRunner.groovy b/src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitlabPipelineRunner.groovy new file mode 100644 index 00000000..310fc8d2 --- /dev/null +++ b/src-gitlabutils/net/sf/jremoterun/utilities/nonjdk/git/lab/GitlabPipelineRunner.groovy @@ -0,0 +1,202 @@ +package net.sf.jremoterun.utilities.nonjdk.git.lab + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.nonjdk.swing.JPanel4FlowLayout +import net.sf.jremoterun.utilities.nonjdk.swing.NameAndTextField +import org.gitlab4j.api.GitLabApi +import org.gitlab4j.api.PipelineApi +import org.gitlab4j.api.RepositoryApi +import org.gitlab4j.api.models.Branch +import org.gitlab4j.api.models.Pipeline +import org.gitlab4j.api.models.PipelineStatus + +import javax.swing.ComboBoxModel +import javax.swing.DefaultComboBoxModel +import javax.swing.JButton +import javax.swing.JComboBox +import javax.swing.JLabel +import javax.swing.JList +import javax.swing.MutableComboBoxModel +import javax.swing.SwingUtilities +import java.awt.event.KeyAdapter +import java.awt.event.KeyEvent; +import java.util.logging.Logger; + +@CompileStatic +abstract class GitlabPipelineRunner { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public enum TextValues { + Run, View, + } + + public JPanel4FlowLayout viewAndPanel = new JPanel4FlowLayout(); + + public GitLabApi gitLabApi; + public NameAndTextField project = new NameAndTextField('project', '', 30); + public JLabel status = new JLabel('') + public JComboBox branchesSwing = new JComboBox() + public JButton runOrView = new JButton(TextValues.Run.name()) + public long intervalChecking = 1000 + public Object lock = new Object(); + public Pipeline pipeline + public Thread thread1; + + GitlabPipelineRunner(GitLabApi gitLabApi,String defaultProject) { + this.gitLabApi = gitLabApi + runOrView.addActionListener { + onClick() + } + project.textField.addKeyListener(new KeyAdapter() { + + + @Override + void keyReleased(KeyEvent keyEvent) { + if (keyEvent.getKeyCode() == KeyEvent.VK_ENTER) { + log.info "new project entered ${getProjectPath()}" + runOrView.setEnabled(false) + refreshBranchesSwingThread() + } + } + }) + doLayout() + project.setText(defaultProject) + refreshBranchesSwingThread() + } + + void refreshBranchesSwingThread(){ + status.setText("Refreshing branches") + Runnable r = { refreshBranches() } + thread1 = new Thread(r, 'Gitlab branches refresh jrr') + thread1.start() + + } + + void doLayout(){ + viewAndPanel.add(project) + viewAndPanel.add(branchesSwing) + viewAndPanel.add(runOrView) + viewAndPanel.add(status) + } + + void onClick() { + String text = runOrView.getText() + if (text == TextValues.Run.name()) { + runOrView.setEnabled(false) + Runnable r = { doRun() } + thread1 = new Thread(r, 'Gitlab pipeline jrr') + thread1.start() + } + if (text == TextValues.View.name()) { + String webUrl = pipeline.getWebUrl() + openUrl(webUrl) + } + } + + abstract void openUrl(String url); + + void refreshBranches() { + String projectPath = getProjectPath() + log.info "refreshing branched for ${projectPath} .." + try { + List branchesS = getBranches() + if(branchesS.size()==0){ + throw new Exception('no branches found') + } + SwingUtilities.invokeLater { + MutableComboBoxModel model = branchesSwing.getModel() as DefaultComboBoxModel + model.removeAllElements() + branchesS.each { + model.addElement(it) + } + branchesSwing.setSelectedIndex(0) + log.info "refresh done branched for ${projectPath}" + status.setText("branches fetched") + } + } catch (Throwable e) { + log.info("Failed refresh ${projectPath}", e) + JrrUtilities.showException("Failed refresh ${projectPath}", e) + SwingUtilities.invokeLater{ + status.setText("branches fetched failed") + } + } finally { + SwingUtilities.invokeLater { + runOrView.setEnabled(true) + } + } + } + + List getBranches(){ + RepositoryApi repositoryApi = gitLabApi.getRepositoryApi() + List branchesO = repositoryApi.getBranches(projectPath) + List branchesS = branchesO.collect { it.getName() } + if(branchesS.contains('master')){ + branchesS.add(0,'master') + } + if(branchesS.contains('main')){ + branchesS.add(0,'main') + } + + branchesS = branchesS.unique() + return branchesS + } + + String getProjectPath() { + return project.getText().trim() + } + + void doRun() { + try { + doRunImpl() + } catch (Throwable e) { + log.info("Failed refresh ${projectPath}", e) + JrrUtilities.showException("Failed run pipeline ${projectPath}", e) + SwingUtilities.invokeLater{ + status.setText("failed run pipeline ${e}") + } + } finally { + SwingUtilities.invokeLater { + runOrView.setText(TextValues.Run.name()) + runOrView.setEnabled(true) + } + } + } + + void doRunImpl() { + PipelineApi pipelineApi = gitLabApi.getPipelineApi() + String projectPath = getProjectPath(); + pipeline = pipelineApi.createPipeline(projectPath, (String) branchesSwing.getSelectedItem()); + SwingUtilities.invokeLater { + runOrView.setText(TextValues.View.name()) + runOrView.setEnabled(true) + } + + while (true) { + if (!onRefreshContinue()) { + break + } + synchronized (lock) { + lock.wait(intervalChecking) + } + pipeline = pipelineApi.getPipeline(projectPath, pipeline.getId()) + } + } + + boolean onRefreshContinue() { + PipelineStatus pipelineStatus = pipeline.getStatus() + SwingUtilities.invokeLater { + status.setText(pipelineStatus.toString()) + } + log.info("pipeline ${pipeline.getId()} ${pipelineStatus}") + if (pipeline.getFinishedAt() != null) { + log.info("pipeline ${pipeline.getId()} finished") + return false + } + return true + + } + + +} diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/AddGroovyToParentCl.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/AddGroovyToParentCl.groovy index cd7ff752..6240ad81 100644 --- a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/AddGroovyToParentCl.groovy +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/AddGroovyToParentCl.groovy @@ -14,7 +14,8 @@ class AddGroovyToParentCl { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - public static AddGroovyToParentCl defaultAddtoParentCl = new AddGroovyToParentCl(); + public static volatile AddGroovyToParentCl defaultAddtoParentCl = new AddGroovyToParentCl(); + void addGroovyJarToParentClassLoader(AddFilesToClassLoaderCommon adderParent){ diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/AddToClassloader.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/AddToClassloader.groovy new file mode 100644 index 00000000..fd5724b9 --- /dev/null +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/AddToClassloader.groovy @@ -0,0 +1,11 @@ +package net.sf.jremoterun.utilities.nonjdk.compiler3 + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon; + +@CompileStatic +interface AddToClassloader { + + void add(AddFilesToClassLoaderCommon adder); + +} \ No newline at end of file diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileGroovyExtMethod.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileGroovyExtMethod.groovy index f81e1896..80192458 100644 --- a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileGroovyExtMethod.groovy +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileGroovyExtMethod.groovy @@ -2,6 +2,7 @@ package net.sf.jremoterun.utilities.nonjdk.compiler3 import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs import java.util.logging.Logger @@ -23,7 +24,7 @@ class CompileGroovyExtMethod extends CompileRequestClient { void compileExtMethods() { - params.addInDir new File(ifDir, "src-logger-ext-methods"); + params.addInDir new File(ifDir, IfFrameworkSrcDirs.src_logger_ext_methods.dirName); params.outputDir = outputDir params.outputDir.mkdirs() params.javaVersion = '1.6' diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileRequestClient.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileRequestClient.groovy index 42243ac6..439e2cc3 100644 --- a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileRequestClient.groovy +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileRequestClient.groovy @@ -7,9 +7,13 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.UrlCLassLoaderUtils import net.sf.jremoterun.utilities.UrlToFileConverter import net.sf.jremoterun.utilities.classpath.AddFilesToUrlClassLoaderGroovy +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.classpath.MavenCommonUtils import net.sf.jremoterun.utilities.javaservice.CallProxy -import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences -import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkResourceDirs +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs import java.util.logging.Logger @@ -18,6 +22,8 @@ class CompileRequestClient implements CompilerRequest { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static ClRef clRefSetCallerClass = new ClRef('net.sf.jremoterun.utilities.nonjdk.compiler3.SetCallerClass'); + public volatile static AddToClassloader addToClassloaderStatic; URLClassLoader loader; AddFilesToUrlClassLoaderGroovy adder; AddFilesToUrlClassLoaderGroovy adderParent; @@ -39,7 +45,7 @@ class CompileRequestClient implements CompilerRequest { return } } - ifDirDefault = GitReferences.ifFramework.resolveToFile() + ifDirDefault = GitSomeRefs.ifFramework.resolveToFile() throw new Exception("Not found ifDir from ${list}") } @@ -64,21 +70,29 @@ class CompileRequestClient implements CompilerRequest { ClassLoader extClassLoader = CreateGroovyClassLoader.findExtClassLoader() URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], extClassLoader) adderParent = new AddFilesToUrlClassLoaderGroovy(urlClassLoader) - AddGroovyToParentCl.defaultAddtoParentCl.addGroovyJarToParentClassLoader(adderParent) + addJarsToParentClassloader() // log.info "extClassLoader : ${extClassLoader.class.name}" loader = CreateGroovyClassLoader.createGroovyClassLoader2(urlClassLoader) adder = new AddFilesToUrlClassLoaderGroovy(loader) - URLClassLoader classLoaderParent = (URLClassLoader) loader.parent - assert classLoaderParent.class == URLClassLoader + URLClassLoader classLoaderParent = (URLClassLoader) loader.getParent() + assert classLoaderParent.getClass() == URLClassLoader // adderParent = new AddFilesToUrlClassLoaderGroovy(classLoaderParent) extMethodsCompiledClasses = new File(ifDir, "build/logger-ext-methods"); + if(addToClassloaderStatic!=null){ + addToClassloaderStatic.add(adder) + } addEclipseCompiler() } + void addJarsToParentClassloader(){ + AddGroovyToParentCl.defaultAddtoParentCl.addGroovyJarToParentClassLoader(adderParent) + } + + void addEclipseCompiler() { - adder.add LatestMavenIds.eclipseJavaCompiler - adder.add LatestMavenIds.eclipseJavaAstParser + adder.add CustObjMavenIds.eclipseJavaCompiler + adder.add CustObjMavenIds.eclipseJavaAstParser } void addExtMethodsDir() { @@ -88,12 +102,14 @@ class CompileRequestClient implements CompilerRequest { assert extMethodsCompiledClasses.listFiles().length > 0 } adder.addF extMethodsCompiledClasses - adder.addF new File(ifDir, "resources-groovy"); + adder.add IfFrameworkResourceDirs.resources_groovy; + //adder.addF new File(ifDir, "resources-groovy"); } void addDirs() { // adder.addF new File(ifDir,"src-logger-ext-methods"); - adder.addF new File(ifDir, "src-groovycompiler"); + adder.add IfFrameworkSrcDirs.src_groovycompiler + //adder.addF new File(ifDir, "src-groovycompiler"); } @@ -106,10 +122,31 @@ class CompileRequestClient implements CompilerRequest { // params.dirs.each { assert it.directory } } + + void doJointCompilationOptions(GroovyCompilerParams params){ + File stubDir2 = params.stubDir + if (stubDir2 == null) { + stubDir2 = params.outputDir + new ClRef('org.codehaus.groovy.tools.javac.JavaStubGenerator'); + } + if (params.keepStubs) { + new ClRef('org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit'); + params.jointCompilationOptions.put("keepStubs", Boolean.TRUE); + } + params.jointCompilationOptions.put("stubDir", stubDir2); + } + void compile(GroovyCompilerParams params) { + if(!params.eclipseCompiler){ + adder.add new MavenCommonUtils().getToolsJarFile() + adder.add IfFrameworkSrcDirs.src_compiler_jdk + } + doJointCompilationOptions(params) checks(params) addDirs() - addExtMethodsDir() + if(params.addExtentionJrrMethods) { + addExtMethodsDir() + } adder.addFileWhereClassLocated JrrClassUtils adder.addFileWhereClassLocated JrrUtils params.addTestClassLoaded JrrClassUtils @@ -127,25 +164,29 @@ class CompileRequestClient implements CompilerRequest { if (params.eclipseCompiler && params.javaVersion == null) { throw new IllegalArgumentException('specify javaVersion') } - + doStdChecks(params) ContextClassLoaderWrapper.wrap2(loader, { + if(params.setCallerClassJava11!=null){ + Map setCallerClassClass = clRefSetCallerClass.newInstance(loader) as Map + setCallerClassClass.get(params.setCallerClassJava11); + } params.testClassLoaded.each { try { - loader.loadClass(it) + loader.loadClass(it.className) } catch (Throwable e) { log.info "failed load class ${it} due to : ${e}" throw e } } params.testClassLoadedSameClassLoader.each { - Class loadedClass = loader.loadClass(it) + Class loadedClass = loader.loadClass(it.className) ClassLoader loader3 = loadedClass.getClassLoader() if (loader3 != loader) { File location = UrlCLassLoaderUtils.getClassLocation(loadedClass) throw new Exception("class ${it} with location ${location} loaded by ${loader3}") } } - Class compileRequestRemoteClass = loader.loadClass(CompileRequestRemote.name); + Class compileRequestRemoteClass = loader.loadClass(CompileRequestRemote.getName()); // assert compileRequestRemoteClass.classLoader == loader Object service = compileRequestRemoteClass.newInstance() CompilerRequest service2 = (CompilerRequest) CallProxy.makeProxy2(CompilerRequest, service); @@ -157,4 +198,31 @@ class CompileRequestClient implements CompilerRequest { } + void doStdChecks(GroovyCompilerParams params){ + //ClRef clRef = new ClRef('org.codehaus.groovy.tools.shell.IO') + params.testNotFoundInParentClassLoaded.each {doStdChecksForClass(it)} + } + + void doStdChecksForClass(ClRef clRef){ + try { + URLClassLoader classloaderParent = adderParent.classloader + Class clazz = clRef.loadClass(classloaderParent); + ClassLoader classLoaderActual = clazz.getClassLoader() + boolean b = classLoaderActual ==classloaderParent + if(!b){ + String addtional = '' + if (classLoaderActual instanceof URLClassLoader) { + URLClassLoader u = (URLClassLoader) classLoaderActual; + addtional = u.getURLs().toList() + } + throw new Exception("class ${clRef} found by ${classLoaderActual} ${addtional}") + } + List uRLS = classloaderParent.getURLs().toList() + throw new Exception("class ${clRef} found by parent classLoader : ${uRLS}") + }catch(ClassNotFoundException e){ + log.fine("class not found as expected",e) + } + } + + } diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileRequestRemote.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileRequestRemote.groovy index 39aa83fb..3a283b29 100644 --- a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileRequestRemote.groovy +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CompileRequestRemote.groovy @@ -1,7 +1,9 @@ package net.sf.jremoterun.utilities.nonjdk.compiler3 import net.sf.jremoterun.JrrUtils; -import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.groovystarter.runners.RunnableWithParamsFactory; + import java.util.logging.Logger; import groovy.transform.CompileStatic; @@ -10,19 +12,25 @@ import groovy.transform.CompileStatic; class CompileRequestRemote implements CompilerRequest { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + ClassLoader classLoader12 = getClass().getClassLoader(); @Override void compile(GroovyCompilerParams params) { + params.classNameRunnerWithParams.each { + RunnableWithParamsFactory.fromClass3(it, classLoader12, params) + } + URL groovyJar = JrrUtils.getClassLocation(GroovyObject) log.fine "groovy jar = ${groovyJar}" - GroovyCompiler groovyCompiler = new GroovyCompiler(params.outputDir,params.eclipseCompiler) - if(params.javaVersion!=null){ + GroovyCompiler groovyCompiler = new GroovyCompiler(params) + if (params.javaVersion != null) { groovyCompiler.setJavaVersion(params.javaVersion); } params.dirs.unique().each { groovyCompiler.addClassesInDirForCompile(it) } - groovyCompiler.unit.addSources(params.files.unique().toArray(new File[0])) + File[] files2 = (File[])params.files.unique().toArray(new File[0]) + groovyCompiler.unit.addSources(files2) // GroovyClassLoader cl = JrrClassUtils.currentClassLoaderGroovy groovyCompiler.additionalFlags.addAll(params.additionalFlags) groovyCompiler.compile() diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CreateGroovyClassLoader.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CreateGroovyClassLoader.groovy index 45e0f88d..3c469b5e 100644 --- a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CreateGroovyClassLoader.groovy +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/CreateGroovyClassLoader.groovy @@ -3,14 +3,20 @@ package net.sf.jremoterun.utilities.nonjdk.compiler3 import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.AddFilesToUrlClassLoaderGroovy +import net.sf.jremoterun.utilities.classpath.ClRef import java.util.logging.Logger @CompileStatic class CreateGroovyClassLoader { - private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + private static ClRef groovyClassloaderClRef = new ClRef('groovy.lang.GroovyClassLoader') + private static ClRef sunClassLoader = new ClRef('sun.misc.Launcher$ExtClassLoader') + private static ClRef jdk11InternalClassLoaderApp = new ClRef('jdk.internal.loader.ClassLoaders$AppClassLoader') + private static ClRef jdk11InternalClassLoader = new ClRef('jdk.internal.loader.ClassLoaders$PlatformClassLoader') + + static URLClassLoader createGroovyClassLoader(ClassLoader parent) { URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], parent) AddFilesToUrlClassLoaderGroovy adder1 = new AddFilesToUrlClassLoaderGroovy(urlClassLoader) @@ -19,31 +25,37 @@ class CreateGroovyClassLoader { } static URLClassLoader createGroovyClassLoader2(ClassLoader urlClassLoader) { - URLClassLoader urlClassLoader2 = urlClassLoader.loadClass(GroovyClassLoader.name).newInstance(urlClassLoader) as URLClassLoader; - assert urlClassLoader2.class.name == GroovyClassLoader.name - assert !urlClassLoader2.class.is(GroovyClassLoader) + URLClassLoader urlClassLoader2 = urlClassLoader.loadClass(groovyClassloaderClRef.className).newInstance(urlClassLoader) as URLClassLoader; + assert urlClassLoader2.getClass().getName() == groovyClassloaderClRef.className + assert !urlClassLoader2.getClass().is(GroovyClassLoader) return urlClassLoader2 } - static URLClassLoader findExtClassLoader() { + static ClassLoader findExtClassLoader() { ClassLoader loader = JrrClassUtils.getCurrentClassLoader() - URLClassLoader classLoader = findExtClassLoaderImpl(loader) + ClassLoader classLoader = findExtClassLoaderImpl(loader) if (classLoader == null) { throw new Exception("failed find ext classloader for ${loader}") } return classLoader } - static URLClassLoader findExtClassLoaderImpl(ClassLoader loader) { + static ClassLoader findExtClassLoaderImpl(ClassLoader loader) { if (loader == null) { return null } - if (loader.class.name == 'sun.misc.Launcher$ExtClassLoader') { - return loader as URLClassLoader + if (loader.getClass().getName() == sunClassLoader.className) { + return loader + } + if (loader.getClass().getName() == jdk11InternalClassLoader.className) { +// ClassLoader classLoaderParent = loader.getParent() +// log.info "classLoaderParent = ${classLoaderParent}" +// return classLoaderParent + return loader; } - return findExtClassLoaderImpl(loader.parent); + return findExtClassLoaderImpl(loader.getParent()); } diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/GroovyCompiler.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/GroovyCompiler.groovy index 664f6f33..3f547f3a 100644 --- a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/GroovyCompiler.groovy +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/GroovyCompiler.groovy @@ -27,30 +27,32 @@ class GroovyCompiler { File outDir final GroovyClassLoader groovyClassLoader3; AddFilesToUrlClassLoaderGroovy addFilesToUrlClassLoaderGroovy; - Map jointCompilationOptions = [:] List additionalFlags = ['-g'] JavacCompilerFactory compilerFactory; boolean eclipseCompiler - GroovyCompiler(File outDir,boolean eclipseCompiler) { - this.eclipseCompiler = eclipseCompiler - if(eclipseCompiler){ - compilerFactory = new EclipseCompilerFactoryC(this) - }else{ - Class clazz = javacCnr.loadClass(JrrClassUtils.currentClassLoader) - compilerFactory = JrrClassUtils.invokeConstructor(clazz,this) as JavacCompilerFactory + GroovyCompiler(GroovyCompilerParams params) { + this.eclipseCompiler = params.eclipseCompiler + if (eclipseCompiler) { + compilerFactory = new EclipseCompilerFactoryC(this, params) + } else { + Class clazz = javacCnr.loadClass(JrrClassUtils.getCurrentClassLoader()) + compilerFactory = JrrClassUtils.invokeConstructor(clazz, this, params) as JavacCompilerFactory } - this.outDir = outDir; + this.outDir = params.outputDir; groovyClassLoader3 = JrrClassUtils.getCurrentClassLoaderGroovy(); addFilesToUrlClassLoaderGroovy = new AddFilesToUrlClassLoaderGroovy(groovyClassLoader3); - jointCompilationOptions.put("stubDir", outDir); - configuration.setJointCompilationOptions(jointCompilationOptions) +// configuration.setDebug(true) -- start failing after enabing debug +// configuration.setVerbose(true) -- useless + configuration.setJointCompilationOptions(params.jointCompilationOptions) assert groovyClassLoader3 != null configuration.setTargetDirectory(outDir) unit = new JavaAwareCompilationUnit(configuration, groovyClassLoader3) unit.setCompilerFactory(compilerFactory) - JrrFieldAccessorSetter.setFieldAccessors(); + if (params.needCustomJrrGroovyFieldsAccessors) { + JrrFieldAccessorSetter.setFieldAccessors(); + } } @@ -61,19 +63,20 @@ class GroovyCompiler { void addClassesInDirForCompile(File dir) { // assert dir.directory - if(dir.isFile()){ + if (dir.isFile()) { unit.addSource(dir) - }else { + } else { assert dir.isDirectory() List files = [] dir.eachFileRecurse(FileType.FILES, { File f = it as File - String name = f.name - if (name.endsWith('.java') || name.endsWith('.groovy')) { + String name1 = f.getName() + if (name1.endsWith('.java') || name1.endsWith('.groovy')) { files.add(f) } }) - unit.addSources(files.toArray(new File[0])) + File[] files1 = (File[]) files.toArray(new File[0]) + unit.addSources(files1) } } @@ -84,7 +87,7 @@ class GroovyCompiler { flags.add(javaVersion2) flags.add('-target') flags.add(javaVersion2) - if(eclipseCompiler){ + if (eclipseCompiler) { flags.add("-${javaVersion2}".toString()) } diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/GroovyCompilerParams.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/GroovyCompilerParams.groovy index eb9aacfe..39d2e332 100644 --- a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/GroovyCompilerParams.groovy +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/GroovyCompilerParams.groovy @@ -2,6 +2,8 @@ package net.sf.jremoterun.utilities.nonjdk.compiler3 import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.classpath.ToFileRef2 import java.util.logging.Logger @@ -12,23 +14,53 @@ class GroovyCompilerParams implements Serializable { List files = []; List dirs = []; + List classNameRunnerWithParams = []; File outputDir; + Boolean setCallerClassJava11; String javaVersion = '1.6';//System.getProperty('java.specification.version') - List testClassLoaded = [] - List testClassLoadedSameClassLoader = [] + List testClassLoaded = [] + + /** + * need use custom groovy jar, where IO class was deleted. Need delete this jar as it depends on other jars, where are not in classpath + */ + List testNotFoundInParentClassLoaded = [new ClRef('org.codehaus.groovy.tools.shell.IO')] + List testClassLoadedSameClassLoader = [] List additionalFlags = [] boolean eclipseCompiler = true; boolean printWarning = false; + boolean addExtentionJrrMethods = true; + boolean needDoStdChecks = true; + boolean needCustomJrrGroovyFieldsAccessors = true + int logJavacInputFilesMaxSize = 50; + List printPathContains = []; + List printPathNotContains = []; + File stubDir; + boolean keepStubs = false + boolean printJavacArgs = false; + Map jointCompilationOptions = [:] + //boolean needAddDefaultClassesToParentCl = true GroovyCompilerParams() { - if(javaVersion==null){ + if (javaVersion == null) { javaVersion = '1.8' } } + void setStdGroovyCompile() { + needCustomJrrGroovyFieldsAccessors = false + addExtentionJrrMethods = false + } + + void addInDir(ToFileRef2 fileRef) { + addInDir fileRef.resolveToFile() + } + void addInDir(File... dirs2) { assert dirs2 != null + if (dirs2.length == 0) { + throw new Exception('dirs array has 0 size') + } for (int i = 0; i < dirs2.length; i++) { File dir = dirs2[i]; assert dir.exists() @@ -42,11 +74,11 @@ class GroovyCompilerParams implements Serializable { } void addTestClassLoadedSameClassLoader(Class clazz) { - testClassLoadedSameClassLoader.add(clazz.name) + testClassLoadedSameClassLoader.add(new ClRef(clazz)) } void addTestClassLoaded(Class clazz) { - testClassLoaded.add(clazz.name) + testClassLoaded.add(new ClRef(clazz)) } } diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/SetCallerClass.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/SetCallerClass.groovy new file mode 100644 index 00000000..3c36c38f --- /dev/null +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/SetCallerClass.groovy @@ -0,0 +1,80 @@ +package net.sf.jremoterun.utilities.nonjdk.compiler3 + +import groovy.transform.CompileStatic +import net.sf.jremoterun.callerclass.GetCallerClassI +import net.sf.jremoterun.callerclass.GetCallerClassS +import net.sf.jremoterun.utilities.classpath.ClRef + +@CompileStatic +class SetCallerClass implements Map{ + +// public static ClRef clRefJava8 = new ClRef("net.sf.jremoterun.callerclass.java8.GetCallerClass") +// public static ClRef clRefJava9 = new ClRef("net.sf.jremoterun.callerclass.java9.GetCallerClass") + + @Override + Object get(Object key) { + doStuff(key as boolean) + return null + } + + void doStuff(boolean isJava11){ + String clRef1 = isJava11? GetCallerClassS.java9ClassImpl:GetCallerClassS.java8ClassImpl + GetCallerClassI instance1 = SetCallerClass.getClassLoader().loadClass(clRef1).newInstance() as GetCallerClassI + GetCallerClassS.getCallerClassI = instance1; + } + + @Override + int size() { + return 0 + } + + @Override + boolean isEmpty() { + return false + } + + @Override + boolean containsKey(Object key) { + return false + } + + @Override + boolean containsValue(Object value) { + return false + } + + @Override + Object put(Object key, Object value) { + return null + } + + @Override + Object remove(Object key) { + return null + } + + @Override + void putAll(Map m) { + + } + + @Override + void clear() { + + } + + @Override + Set keySet() { + return null + } + + @Override + Collection values() { + return null + } + + @Override + Set entrySet() { + return null + } +} diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseCompiler3.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseCompiler3.groovy index d0d3ef91..c0ad617a 100644 --- a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseCompiler3.groovy +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseCompiler3.groovy @@ -2,6 +2,8 @@ package net.sf.jremoterun.utilities.nonjdk.compiler3.eclipse import groovy.transform.CompileStatic import org.eclipse.jdt.core.compiler.CompilationProgress +import org.eclipse.jdt.internal.compiler.ClassFile +import org.eclipse.jdt.internal.compiler.CompilationResult import java.util.logging.Logger @@ -10,10 +12,31 @@ class EclipseCompiler3 extends org.eclipse.jdt.internal.compiler.batch.Main{ // private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - EclipseCompiler3(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map customDefaultOptions, CompilationProgress compilationProgress) { + public Map> myOutputs = new HashMap<>(); + public boolean rememberOutput; + + EclipseCompiler3(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map customDefaultOptions, CompilationProgress compilationProgress,boolean rememberOutput) { super(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, compilationProgress) + this.rememberOutput = rememberOutput } + public void outputClassFiles(CompilationResult result) { + super.outputClassFiles(result); + if(rememberOutput) { + if (result == null || result.hasErrors() && !proceedOnError) { + return; + } + + List classFiles = new ArrayList<>(); + for (ClassFile file : result.getClassFiles()) { + classFiles.add(new String(file.fileName()) + ".class"); + } + myOutputs.put(new File(new String(result.getFileName())), classFiles); + } + } - + @Override + boolean compile(String[] argv) { + return super.compile(argv) + } } diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseCompilerFactoryC.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseCompilerFactoryC.groovy index c6e1a424..a9402b1b 100644 --- a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseCompilerFactoryC.groovy +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseCompilerFactoryC.groovy @@ -3,6 +3,7 @@ package net.sf.jremoterun.utilities.nonjdk.compiler3.eclipse import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.nonjdk.compiler3.GroovyCompiler +import net.sf.jremoterun.utilities.nonjdk.compiler3.GroovyCompilerParams import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.tools.javac.JavaCompiler import org.codehaus.groovy.tools.javac.JavacCompilerFactory @@ -21,15 +22,18 @@ class EclipseCompilerFactoryC extends JavacCompilerFactory{ EclipseJavaCompiler2C javaCompilerC ; - GroovyCompiler groovyCompiler + GroovyCompiler groovyCompiler; - EclipseCompilerFactoryC(GroovyCompiler groovyCompiler) { + GroovyCompilerParams params; + + EclipseCompilerFactoryC(GroovyCompiler groovyCompiler, GroovyCompilerParams params) { this.groovyCompiler = groovyCompiler + this.params = params; } @Override JavaCompiler createCompiler(CompilerConfiguration config) { - javaCompilerC = new EclipseJavaCompiler2C(config,groovyCompiler) + javaCompilerC = new EclipseJavaCompiler2C(config,groovyCompiler,params) return javaCompilerC; } } diff --git a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseJavaCompiler2C.groovy b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseJavaCompiler2C.groovy index 5d43735d..ec2ed87f 100644 --- a/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseJavaCompiler2C.groovy +++ b/src-groovycompiler/net/sf/jremoterun/utilities/nonjdk/compiler3/eclipse/EclipseJavaCompiler2C.groovy @@ -4,6 +4,7 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.JrrUtils import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.nonjdk.compiler3.GroovyCompiler +import net.sf.jremoterun.utilities.nonjdk.compiler3.GroovyCompilerParams import org.codehaus.groovy.control.CompilationUnit import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.messages.SimpleMessage @@ -19,14 +20,59 @@ public class EclipseJavaCompiler2C implements JavaCompiler { private CompilerConfiguration config; // List additionalFlags = [] GroovyCompiler groovyCompiler; + GroovyCompilerParams params; + public boolean rememberOutput = false - public EclipseJavaCompiler2C(CompilerConfiguration config, GroovyCompiler groovyCompiler) { + public EclipseJavaCompiler2C(CompilerConfiguration config, GroovyCompiler groovyCompiler,GroovyCompilerParams params) { this.config = config; this.groovyCompiler = groovyCompiler + this.params = params; + if(params==null){ + throw new NullPointerException('params is null'); + } + } + + void printDebug(List files){ + if(params.printPathNotContains.size()>0){ + List file3 = files.findAll { isFileNotMatched(it) } + if(file3.size()==0){ + log.info "tmpr filtered skip compiling files has zero files" + }else { + List file4 = file3; + if (file4.size() > params.logJavacInputFilesMaxSize) { + file4 = file4.subList(0, params.logJavacInputFilesMaxSize) + } + log.info "tmpr filtered skip compiling files ${file3.size()} : ${file4}" + } + } + if(params.printPathContains.size()>0){ + List file3 = files.findAll { isFileMatched(it) } + if(file3.size()==0){ + log.info "filtered compiling files has zero files" + }else { + List file4 = file3; + if (file4.size() > params.logJavacInputFilesMaxSize) { + file4 = file4.subList(0, params.logJavacInputFilesMaxSize) + } + log.info "filtered compiling files ${file3.size()} : ${file4}" + } + } + } + + boolean isFileNotMatched(String path1){ + String find1 = params.printPathNotContains.find { path1.contains(it) }; + return find1==null + } + + boolean isFileMatched(String path1){ + String find1 = params.printPathContains.find { path1.contains(it) }; + return find1!=null } @Override public void compile(List files, CompilationUnit cu) { + log.info "compiling stubs ..." + printDebug(files) String[] javacParameters = makeParameters(files, cu.getClassLoader()); StringWriter javacOutput = new StringWriter(); PrintWriter writer = new PrintWriter(javacOutput); @@ -37,6 +83,7 @@ public class EclipseJavaCompiler2C implements JavaCompiler { if (trim2.length() > 0) { log.info "${trim2}"; } + log.info "compiling stubs finished fine" } else { String header = "Compile error \n${javacOutput}" cu.getErrorCollector().addFatalError(new SimpleMessage(header, cu)); @@ -50,7 +97,7 @@ public class EclipseJavaCompiler2C implements JavaCompiler { // log.info "compilerClassLocaton = ${compilerClassLocaton}" // log.info "compilerClassLocaton = ${JrrUtils.getClassLocation(org.eclipse.jdt.internal.compiler.apt.util.EclipseFileManager)}" - EclipseCompiler3 compiler3 = new EclipseCompiler3(writer, writer, false, null, null) + EclipseCompiler3 compiler3 = new EclipseCompiler3(writer, writer, false, null, null,rememberOutput) // javacParameters = ['-help'] // log.info "${Arrays.toString javacParameters}" boolean compile = compiler3.compile(javacParameters) @@ -122,7 +169,9 @@ public class EclipseJavaCompiler2C implements JavaCompiler { // files to compile params.addAll(files); - + if(this.params.printJavacArgs) { + log.info "javacArgs : ${params}" + } return params.toArray(new String[params.size()]); } diff --git a/src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/JrrText2Speech.groovy b/src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/JrrText2Speech.groovy new file mode 100644 index 00000000..81cde491 --- /dev/null +++ b/src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/JrrText2Speech.groovy @@ -0,0 +1,67 @@ +package net.sf.jremoterun.utilities.nonjdk.audio + +import groovy.transform.CompileStatic +import marytts.LocalMaryInterface; +import net.sf.jremoterun.utilities.JrrClassUtils + +import javax.sound.sampled.AudioInputStream +import javax.sound.sampled.AudioSystem +import javax.sound.sampled.Clip +import javax.sound.sampled.Mixer; +import java.util.logging.Logger; + +@CompileStatic +class JrrText2Speech { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static List devicesToPlayDefault = [] + public static JrrText2Speech defaultTts = new JrrText2Speech() + public static Date lastPlayed; + + List getAllDevicesToPlay() { + Mixer.Info[] info1 = AudioSystem.getMixerInfo(); + List list1 = info1.toList() + list1 = list1.findAll { isSupported(it) }; + return list1 + } + + static void playTextOnAllDevicesS(String text) { + defaultTts.playTextOnAllDevices(text) + } + + void playTextOnAllDevices(String text) { + List info1 = getAllDevicesToPlay() + if (info1.size() == 0) { + throw new Exception('No devices to play') + } + info1.each { + playTextOnDevice(text, it) + } + } + + boolean isSupported(Mixer.Info info) { + if (!info.getClass().getName().endsWith('DirectAudioDeviceInfo')) { + return false + } + String name = info.getName() + String find1 = devicesToPlayDefault.find { it.length() > 1 && name.contains(it) } + return find1 != null + } + + Clip playTextOnDevice(String text, Mixer.Info device) { + AudioInputStream audio = createAudioStream(text); + Clip audioclip = AudioSystem.getClip(device); + log.info "class name = ${audioclip.getClass().getName()}" + audioclip.open(audio); + audioclip.start(); + lastPlayed = new Date() + return audioclip; + } + + AudioInputStream createAudioStream(String text) { + LocalMaryInterface mary = new LocalMaryInterface(); + AudioInputStream audio = mary.generateAudio(text); + return audio + } + +} diff --git a/src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/idea/IdeaClasspathImportFailed.groovy b/src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/idea/IdeaClasspathImportFailed.groovy new file mode 100644 index 00000000..e2988dc5 --- /dev/null +++ b/src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/idea/IdeaClasspathImportFailed.groovy @@ -0,0 +1,41 @@ +package net.sf.jremoterun.utilities.nonjdk.audio.idea + +import groovy.transform.CompileStatic +import idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.IdeaAddFileWithSources +import idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.LibManager3; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.NewValueListener +import net.sf.jremoterun.utilities.nonjdk.audio.JrrText2Speech + +import java.util.logging.Level; +import java.util.logging.Logger; + +@CompileStatic +class IdeaClasspathImportFailed implements NewValueListener { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void newValue(Throwable throwable) { + try { + JrrUtilities.showException('Classpath imported failed', throwable) + String msg = 'Classpath imported failed : ' + throwable; + if(msg.length()>100){ + msg = msg.substring(0,99) + } + JrrText2Speech.playTextOnAllDevicesS(msg) + } catch (Throwable e) { + log.log(Level.SEVERE,"failed play audio",e) + JrrUtilities.showException('failed play audio', e) + } + } + + + static void init1(){ + marytts.util.MaryRuntimeUtils.ensureMaryStarted() + LibManager3.importFinishedFine = new IdeaClasspathImportedFine(); + IdeaClasspathImportFailed importFailed = new IdeaClasspathImportFailed() + IdeaAddFileWithSources.importFailed = importFailed; + LibManager3.importFailed = importFailed; + } +} diff --git a/src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/idea/IdeaClasspathImportedFine.groovy b/src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/idea/IdeaClasspathImportedFine.groovy new file mode 100644 index 00000000..18af1e2b --- /dev/null +++ b/src-idea-audio/net/sf/jremoterun/utilities/nonjdk/audio/idea/IdeaClasspathImportedFine.groovy @@ -0,0 +1,24 @@ +package net.sf.jremoterun.utilities.nonjdk.audio.idea + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.nonjdk.audio.JrrText2Speech + +import java.util.logging.Level; +import java.util.logging.Logger; + +@CompileStatic +class IdeaClasspathImportedFine implements Runnable{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void run() { + try { + JrrText2Speech.playTextOnAllDevicesS('Classpath imported to Idea fine') + }catch(Throwable e){ + log.log(Level.SEVERE,"failed play audio",e) + JrrUtilities.showException('failed play audio',e) + } + } +} diff --git a/src-idea-github/net/sf/jremoterun/utilities/nonjdk/idea/github/IdeaGitgubAddRepo.groovy b/src-idea-github/net/sf/jremoterun/utilities/nonjdk/idea/github/IdeaGitgubAddRepo.groovy new file mode 100644 index 00000000..4f7eb76d --- /dev/null +++ b/src-idea-github/net/sf/jremoterun/utilities/nonjdk/idea/github/IdeaGitgubAddRepo.groovy @@ -0,0 +1,39 @@ +package net.sf.jremoterun.utilities.nonjdk.idea.github + +import com.intellij.dvcs.repo.Repository +import com.intellij.dvcs.repo.VcsRepositoryManager +import com.intellij.openapi.Disposable +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Disposer +import com.intellij.openapi.vfs.VirtualFile +import git4idea.repo.GitRepository +import git4idea.repo.GitRepositoryImpl +import git4idea.repo.GitRepositoryManager +import groovy.transform.CompileStatic +import idea.plugins.thirdparty.filecompletion.share.OSIntegrationIdea; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class IdeaGitgubAddRepo { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static void addRepoD(File gitRepoDir){ + addRepo(gitRepoDir,OSIntegrationIdea.getOpenedProject()) + } + + static void addRepo(File gitRepoDir,Project openedProject){ + VcsRepositoryManager vcsRepositoryManager = VcsRepositoryManager.getInstance(openedProject); + VirtualFile virtualFile = OSIntegrationIdea.conevertFileToVirtual(gitRepoDir) + GitRepositoryManager gitRepositoryManager = GitRepositoryManager.getInstance(openedProject) + GitRepository gitRepository = gitRepositoryManager.getRepositoryForFile(virtualFile) + if(gitRepository==null){ + Disposable disposable = Disposer.newDisposable() + gitRepository = GitRepositoryImpl.createInstance(virtualFile,openedProject,disposable,true); + gitRepositoryManager.addExternalRepository(virtualFile,gitRepository); + } + Map myRepos = JrrClassUtils.getFieldValue(vcsRepositoryManager,'myRepositories') as Map + myRepos.put(virtualFile,gitRepository) + } + +} diff --git a/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBRunnerImpl.java b/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBRunnerImpl.java index 7aa3dedf..1aa37dea 100644 --- a/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBRunnerImpl.java +++ b/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBRunnerImpl.java @@ -1,12 +1,13 @@ package net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild; import groovy.lang.GroovyClassLoader; +import org.jetbrains.jps.cmdline.LauncherOriginal; import java.io.File; +import java.io.FileNotFoundException; import java.util.logging.Logger; - public class IdeaBRunnerImpl implements Runnable { private static final Logger log = Logger.getLogger(IdeaBRunnerImpl.class.getName()); @@ -23,14 +24,22 @@ public void run() { void f1() throws Exception { log.info("cp5"); - GroovyClassLoader groovyClassLoader = (GroovyClassLoader) IdeaBuilderAddGroovyRuntime.groovyCl; - File f = new File(System.getProperty("user.home")+"/jrr/configs/idea_builder.groovy"); - log.info("loading config : "+f); - Class aClass = groovyClassLoader.parseClass(f); - Runnable instance = (Runnable) aClass.newInstance(); - log.info("running : "+aClass); - instance.run(); - log.info("cp7"); + GroovyClassLoader groovyClassLoader = (GroovyClassLoader) IdeaBuildRunnerSettings.groovyCl; + log.info("loading config : "+IdeaBuildRunnerSettings.ideaBuilderConfigFile); + if(IdeaBuildRunnerSettings.ideaBuilderConfigFile.exists()) { + Class aClass = groovyClassLoader.parseClass(IdeaBuildRunnerSettings.ideaBuilderConfigFile); + Runnable instance = (Runnable) aClass.newInstance(); + log.info("running : " + aClass); + instance.run(); + log.info("cp7"); + }else{ + log.info("idea config file not exists : "+IdeaBuildRunnerSettings.ideaBuilderConfigFile); + if(IdeaBuildRunnerSettings.startOriginal){ + LauncherOriginal.main(IdeaBuildRunnerSettings.argsPv2.toArray(new String[0])); + }else{ + throw new FileNotFoundException(IdeaBuildRunnerSettings.ideaBuilderConfigFile.getAbsolutePath()); + } + } } } diff --git a/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBuildRunnerSettings.java b/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBuildRunnerSettings.java new file mode 100644 index 00000000..76377431 --- /dev/null +++ b/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBuildRunnerSettings.java @@ -0,0 +1,46 @@ +package net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild; + +import java.io.File; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.URLClassLoader; +import java.util.Date; +import java.util.List; + +public class IdeaBuildRunnerSettings { + public static String jrrUseOneJarS = "jrrUseOneJar"; + public static String jrrStartOriginalIfJrrMissingS = "jrrStartOriginalIfJrrMissing"; + public static String jrrStartShowExceptionInSwingS = "jrrStartShowExceptionInSwing"; + public static String jrrIdeaRedirectOutToFileAuxS = "jrrIdeaRedirectOutToFileAux"; + public static String jrrIdeaForceUseStdS = "jrrIdeaForceUseStd"; + public static String jrrpathS = "jrrpath"; + public static File jrrlibpathF = new File(System.getProperty("user.home") + "/jrr/configs/jrrlibpath.txt"); + public static File buildLogBefore = new File(System.getProperty("user.home") + "/idea_build_jrr_log.txt"); + + public static volatile boolean redirectOutToFileAux = ("true".equalsIgnoreCase(System.getProperty(jrrIdeaRedirectOutToFileAuxS))); + public static volatile boolean jrrIdeaForceUseStd = ("true".equalsIgnoreCase(System.getProperty(jrrIdeaForceUseStdS))); + public static volatile boolean useOneJar = !("false".equalsIgnoreCase(System.getProperty(jrrUseOneJarS))); + public static volatile boolean startOriginal = !("false".equalsIgnoreCase(System.getProperty(jrrStartOriginalIfJrrMissingS))); + public static volatile boolean originalTried = false; + public static volatile boolean jrrStartShowExceptionInSwing = !("false".equalsIgnoreCase(System.getProperty(jrrStartShowExceptionInSwingS))); + public static volatile URLClassLoader groovyCl; + public static volatile File jrrpathF; + public static volatile File outputFile; + public static volatile Runnable beforeMainOriginalRun; + + public static volatile File userHome = new File(System.getProperty("user.home")); + public static volatile File ideaBuilderConfigFile = new File(userHome, "jrr/configs/ideaBuilder.groovy"); + public static Date startDate = new Date(); + + //public static volatile String[] argsP; + public static volatile List argsPv2; + + public static PrintStream originalOut = System.out; + public static PrintStream originalErr = System.err; + public static volatile PrintStream jrrOutStream; + + + + + +} diff --git a/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBuilderAddGroovyRuntime.java b/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBuilderAddGroovyRuntime.java index 8555b7e2..b680ea60 100644 --- a/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBuilderAddGroovyRuntime.java +++ b/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/IdeaBuilderAddGroovyRuntime.java @@ -1,38 +1,113 @@ package net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild; -import java.io.File; -import java.io.FileNotFoundException; +import org.jetbrains.jps.cmdline.LauncherOriginal; + +import java.io.*; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.util.Date; import java.util.logging.Logger; public class IdeaBuilderAddGroovyRuntime { private static final Logger log = Logger.getLogger(IdeaBuilderAddGroovyRuntime.class.getName()); -// static File jrrPathDefault = new File("c:/Users/nick/git/starter"); - public static URLClassLoader groovyCl; + public static void f1() throws Exception { + try { + if(IdeaBuildRunnerSettings.redirectOutToFileAux){ + doRedirect(); + } + if(IdeaBuildRunnerSettings.jrrIdeaForceUseStd){ + log.info("force use LauncherOriginal"); + runOriginal(); + }else { + doJobImpl(); + } + }catch (Throwable e){ + e.printStackTrace(); + if(IdeaBuildRunnerSettings.startOriginal){ + if(IdeaBuildRunnerSettings.originalTried){ + throw e; + } + runOriginal(); + } + } + } + + + public static void doRedirect() throws Exception { + + //FileOutputStream fous = new FileOutputStream(jrrlibpath); + PrintStream printStream1= new PrintStream(IdeaBuildRunnerSettings.buildLogBefore); + IdeaBuildRunnerSettings.jrrOutStream = printStream1; + System.setOut(printStream1); + System.setErr(printStream1); + System.out.println("starting "+new Date()); + } - static void f1() throws Exception { + public static void doJobImpl() throws Exception { log.info("starting ..."); - String jrrpath = System.getProperty("jrrpath"); - log.info("jrrpath = " + jrrpath); - if (jrrpath == null) { + IdeaBuildRunnerSettings.jrrpathF = detectJrrPath(); + log.info("jrrpath = " + IdeaBuildRunnerSettings.jrrpathF); + if (IdeaBuildRunnerSettings.jrrpathF == null) { log.severe("jrrpath is null "); - throw new Exception("jrrpath is null "); - } + if(IdeaBuildRunnerSettings.startOriginal){ + runOriginal(); + }else { + throw new Exception("jrrpath is null "); + } + }else { // jrrpath = jrrPathDefault.getAbsolutePath(); - File f = new File(jrrpath); - if (!f.exists()) { - throw new FileNotFoundException(f.getAbsolutePath()); + if (!IdeaBuildRunnerSettings.jrrpathF.exists()) { + throw new FileNotFoundException(IdeaBuildRunnerSettings.jrrpathF.getAbsolutePath()); + } + log.info("cp3"); + f2(IdeaBuildRunnerSettings.jrrpathF); + log.info("finished fine"); } - log.info("cp3"); - f2(f); - log.info("finished fine"); + } + + static void runOriginal() throws MalformedURLException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, IllegalAccessException, InstantiationException { + LauncherOriginal.main(IdeaBuildRunnerSettings.argsPv2.toArray(new String[0])); + } + public static File detectJrrPath() throws Exception { + String jrrpath = System.getProperty(IdeaBuildRunnerSettings.jrrpathS); + log.info("jrrpath sys prop = " + jrrpath); + if(jrrpath!=null){ + File f = new File(jrrpath); + if(!f.exists()){ + throw new FileNotFoundException(f.getAbsolutePath()); + } + return f; + } + boolean jrrlibpathE = IdeaBuildRunnerSettings.jrrlibpathF.exists(); + log.info("jrrlibpath exit : "+jrrlibpathE+" "+IdeaBuildRunnerSettings.jrrlibpathF); + if(jrrlibpathE){ + FileInputStream fis = new FileInputStream(IdeaBuildRunnerSettings.jrrlibpathF); + try{ + byte[] buff= new byte[10000]; + int read = fis.read(buff); + if(read<2){ + throw new IOException("Failed read : "+IdeaBuildRunnerSettings.jrrlibpathF.getAbsolutePath()); + } + String pathFromFileS = new String(buff, 0, read).trim(); + log.info("jrr path from file : "+pathFromFileS); + File jrrLibPath2 = new File(pathFromFileS); + if(!jrrLibPath2.exists()){ + throw new FileNotFoundException(jrrLibPath2.getAbsolutePath()); + } + return jrrLibPath2; + }finally { + fis.close(); + } + } + return null; } static void f2(File jrrpath) throws Exception { @@ -45,27 +120,27 @@ static void f2(File jrrpath) throws Exception { log.info("creating groovy cl"); Class aClass = classLoader.loadClass("groovy.lang.GroovyClassLoader"); Constructor constructor = aClass.getConstructor(ClassLoader.class); - groovyCl = (URLClassLoader) constructor.newInstance(classLoader); + IdeaBuildRunnerSettings.groovyCl = (URLClassLoader) constructor.newInstance(classLoader); - addUrlToCl(groovyCl, new File(copyDir, "jremoterun.jar")); - addUrlToCl(groovyCl, new File(copyDir, "jrrassist.jar")); - addUrlToCl(groovyCl, new File(jrrpath, "JrrInit/src")); - if (true) { - addUrlToCl(groovyCl, new File(jrrpath, "onejar/jrrutilities.jar ")); + addUrlToCl(IdeaBuildRunnerSettings.groovyCl, new File(copyDir, "jremoterun.jar")); + addUrlToCl(IdeaBuildRunnerSettings.groovyCl, new File(copyDir, "jrrassist.jar")); + addUrlToCl(IdeaBuildRunnerSettings.groovyCl, new File(jrrpath, "JrrInit/src")); + if (IdeaBuildRunnerSettings.useOneJar) { + addUrlToCl(IdeaBuildRunnerSettings.groovyCl, new File(jrrpath, "onejar/jrrutilities.jar")); } else { - addUrlToCl(groovyCl, new File(jrrpath, "JrrUtilities/src")); - addUrlToCl(groovyCl, new File(jrrpath, "JrrStarter/src")); + addUrlToCl(IdeaBuildRunnerSettings.groovyCl, new File(jrrpath, "JrrUtilities/src")); + addUrlToCl(IdeaBuildRunnerSettings.groovyCl, new File(jrrpath, "JrrStarter/src")); } log.info("jars added to groovy cl"); - Thread.currentThread().setContextClassLoader(groovyCl); - Class aClass1 = groovyCl.loadClass("net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.IdeaBRunnerImpl"); + Thread.currentThread().setContextClassLoader(IdeaBuildRunnerSettings.groovyCl); + Class aClass1 = IdeaBuildRunnerSettings.groovyCl.loadClass("net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.IdeaBRunnerImpl"); Runnable o = (Runnable) aClass1.newInstance(); log.info("running " + aClass1); o.run(); } - static Method addUrlM; + public static Method addUrlM; static void addUrlToCl(URLClassLoader cl, File jrrpath) throws Exception { log.info("adding to CL : " + jrrpath); diff --git a/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/LauncherImpl.java b/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/LauncherImpl.java index 6e7af7db..dec74c95 100644 --- a/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/LauncherImpl.java +++ b/src-idea-launcher/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild/LauncherImpl.java @@ -1,17 +1,19 @@ package net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; public class LauncherImpl { - public static String[] argsP; - public static Date startDate = new Date(); - - - public static void main(String[] args) throws Exception { - argsP = args; - IdeaBuilderAddGroovyRuntime.f1(); + IdeaBuildRunnerSettings.argsPv2 = new ArrayList<>( Arrays.asList(args)); + try { + IdeaBuilderAddGroovyRuntime.f1(); + } catch (Throwable e) { + e.printStackTrace(); + throw e; + } } diff --git a/src-idea-launcher/org/jetbrains/jps/cmdline/Launcher.java b/src-idea-launcher/org/jetbrains/jps/cmdline/Launcher.java index 4c005af9..1b0ad520 100644 --- a/src-idea-launcher/org/jetbrains/jps/cmdline/Launcher.java +++ b/src-idea-launcher/org/jetbrains/jps/cmdline/Launcher.java @@ -20,10 +20,6 @@ import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; -/** - * @author Eugene Zhuravlev - * Date: 9/27/13 - */ public class Launcher { public static void main(String[] args) throws Exception { diff --git a/src-idea-launcher/org/jetbrains/jps/cmdline/LauncherOriginal.java b/src-idea-launcher/org/jetbrains/jps/cmdline/LauncherOriginal.java new file mode 100644 index 00000000..27e84e69 --- /dev/null +++ b/src-idea-launcher/org/jetbrains/jps/cmdline/LauncherOriginal.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jps.cmdline; + +import net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.IdeaBuildRunnerSettings; +import net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.IdeaBuilderAddGroovyRuntime; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.StringTokenizer; + +public class LauncherOriginal { + + public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { + IdeaBuildRunnerSettings.originalTried = true; + final String jpsClasspath = args[0]; + final String mainClassName = args[1]; + final String[] jpsArgs = new String[args.length - 2]; + System.arraycopy(args, 2, jpsArgs, 0, jpsArgs.length); + + final StringTokenizer tokenizer = new StringTokenizer(jpsClasspath, File.pathSeparator, false); + final List urls = new ArrayList<>(); + while (tokenizer.hasMoreTokens()) { + final String path = tokenizer.nextToken(); + urls.add(new File(path).toURI().toURL()); + } + final URLClassLoader jpsLoader = new URLClassLoader(urls.toArray(new URL[0]), Launcher.class.getClassLoader()); + + // IDEA-120811; speeding up DefaultChannelIDd calculation for netty + //if (Boolean.parseBoolean(System.getProperty("io.netty.random.id"))) { + System.setProperty("io.netty.machineId", "28:f0:76:ff:fe:16:65:0e"); + System.setProperty("io.netty.processId", Integer.toString(new Random().nextInt(65535))); + System.setProperty("io.netty.serviceThreadPrefix", "Netty"); + //} + + final Class mainClass = jpsLoader.loadClass(mainClassName); + final Method mainMethod = mainClass.getMethod("main", String[].class); + Thread.currentThread().setContextClassLoader(jpsLoader); + mainMethod.invoke(null, new Object[] {jpsArgs}); + } + +} diff --git a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/compile/IdeaRunnerBuilderCompiler.groovy b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/compile/IdeaRunnerBuilderCompiler.groovy index 5117061d..7538782b 100644 --- a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/compile/IdeaRunnerBuilderCompiler.groovy +++ b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/compile/IdeaRunnerBuilderCompiler.groovy @@ -2,54 +2,68 @@ package net.sf.jremoterun.utilities.nonjdk.compile import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs +import net.sf.jremoterun.utilities.nonjdk.InfocationFrameworkStructure import net.sf.jremoterun.utilities.nonjdk.antutils.JrrAntUtils import net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.IdeaBuilderAddGroovyRuntime +import net.sf.jremoterun.utilities.nonjdk.javacompiler.EclipseJavaCompilerPure import org.jetbrains.jps.cmdline.Launcher -import org.junit.Test +import org.zeroturnaround.zip.ZipUtil import java.util.logging.Logger @CompileStatic -class IdeaRunnerBuilderCompiler extends GenericCompiler { +class IdeaRunnerBuilderCompiler { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - public static List mavenIds = [ + public EclipseJavaCompilerPure compilerPure = new EclipseJavaCompilerPure(); + public static List mavenIds = [ + DropshipClasspath.groovy ] - File baseDir + public File baseDir void prepare() { if(baseDir==null){ - baseDir = client.ifDir + baseDir = InfocationFrameworkStructure.ifDir; } assert baseDir!=null - params.javaVersion = '1.8' - params.addInDir new File(baseDir,'src-idea-launcher') -// client.adder.addAll mavenIds - params.outputDir = new File(baseDir, 'build/idearunner') + compilerPure.javaVersion = '1.8' + + compilerPure.addInDir IfFrameworkSrcDirs.src_idea_launcher +// params.addInDir new File(baseDir,'src-idea-launcher') + compilerPure.adder.addAll mavenIds + compilerPure.outputDir = new File(baseDir, 'build/idearunner') } - @Test - @Override - void all2() { - super.all2() - } + File createCustomJar() { + File fileJar = new File(baseDir, 'build/jps-launcher.jar') + fileJar.delete(); + assert !fileJar.exists() + ZipUtil.pack(compilerPure.outputDir, fileJar) + return fileJar; + } + void updateCompiler(File compilerJar) { List classes3 = (List) [Launcher,] classes3.each { - JrrAntUtils.addClassToZip2(compilerJar, params.outputDir, it) + JrrAntUtils.addClassToZip2(compilerJar, compilerPure.outputDir, it) } - JrrAntUtils.addPackageToZip(compilerJar, params.outputDir, IdeaBuilderAddGroovyRuntime) + JrrAntUtils.addPackageToZip(compilerJar, compilerPure.outputDir, IdeaBuilderAddGroovyRuntime) } - File zipp(){ - return null + static File getJarFile(File ideaPath){ + assert ideaPath.exists() + File f = ideaPath.child('plugins/java/lib/jps-launcher.jar'); + assert f.exists() + return f; } diff --git a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/AddMavenIds.groovy b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/AddMavenIds.groovy index 1b712533..cb3a3d0d 100644 --- a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/AddMavenIds.groovy +++ b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/AddMavenIds.groovy @@ -3,6 +3,7 @@ package net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild2 import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import java.util.logging.Logger @@ -22,7 +23,7 @@ class AddMavenIds implements Runnable { void f1() { - IdeaBRunner21.adder.add LatestMavenIds.commonsIo + IdeaBRunner21.adder.add CustObjMavenIds.commonsIo IdeaBRunner21.adder.addAll DropshipClasspath.allLibsWithoutGroovy } } diff --git a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner21.groovy b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner21.groovy index 52e05b21..938ac314 100644 --- a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner21.groovy +++ b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner21.groovy @@ -28,7 +28,7 @@ class IdeaBRunner21 extends InjectedCode { return null } - void f1(File ifBaseDir) { + static void f1(File ifBaseDir) { log.info "loading framework" assert ifBaseDir.exists() adder.add ifBaseDir.child("src-frameworkloader") diff --git a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner33.groovy b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner33.groovy index 2b55bd56..24b6a46b 100644 --- a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner33.groovy +++ b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner33.groovy @@ -2,9 +2,11 @@ package net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild2 import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.groovystarter.runners.ClRefRef import net.sf.jremoterun.utilities.groovystarter.runners.RunnableFactory +import net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.IdeaBuildRunnerSettings import net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.LauncherImpl import java.util.logging.Logger @@ -14,7 +16,9 @@ class IdeaBRunner33 implements Runnable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - static enum A implements ClRefRef { + public static volatile AddFilesToClassLoaderGroovy adder2; + + public static enum A implements ClRefRef { addMavenIds(new ClRef('net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild2.AddMavenIds')), ivyDepSetter(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.IvyDepResolverSetter')), redir(new ClRef('net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild2.Redirector')), @@ -33,15 +37,355 @@ class IdeaBRunner33 implements Runnable { } - void f1() { + static void f1() { log.info "loading framework2" RunnableFactory.runRunner A.addMavenIds RunnableFactory.runRunner A.ivyDepSetter RunnableFactory.runRunner A.redir log.info "redirector set 2" - long delay = System.currentTimeMillis() - LauncherImpl.startDate.getTime() - log.info "startup delay : ${delay / 1000} s" RunnableFactory.runRunner A.runnerImpl + new ClRef('org.jetbrains.jps.incremental.groovy.GroovycOutputParser'); + new ClRef('org.jetbrains.jps.incremental.groovy.GreclipseBuilder'); + // goovyc compiler + new ClRef('org.jetbrains.groovy.compiler.rt.GroovyCompilerWrapper'); + new ClRef('org.jetbrains.groovy.compiler.rt.DependentGroovycRunner'); + } } + + +/* +SEVERE failed load org.codehaus.groovy.runtime.SqlGroovyMethods java.lang.ClassNotFoundException: org.codehaus.groovy.runtime.SqlGroovyMethods + at java.net.URLClassLoader.findClass(URLClassLoader.java:382) + at java.lang.ClassLoader.loadClass(ClassLoader.java:418) + at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:869) + at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:979) + at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:967) + at org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule.loadExtensionClass(MetaInfExtensionModule.java:88) + at org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule.newModule(MetaInfExtensionModule.java:73) + at org.codehaus.groovy.runtime.m12n.StandardPropertiesModuleFactory.newModule(StandardPropertiesModuleFactory.java:50) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanExtensionModuleFromProperties(ExtensionModuleScanner.java:86) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanExtensionModuleFromMetaInf(ExtensionModuleScanner.java:81) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanClasspathModulesFrom(ExtensionModuleScanner.java:63) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanClasspathModules(ExtensionModuleScanner.java:55) + at org.codehaus.groovy.transform.stc.AbstractExtensionMethodCache.getMethodsFromClassLoader(AbstractExtensionMethodCache.java:71) + at org.codehaus.groovy.runtime.memoize.StampedCommonCache.compute(StampedCommonCache.java:163) + at org.codehaus.groovy.runtime.memoize.StampedCommonCache.getAndPut(StampedCommonCache.java:154) + at org.codehaus.groovy.runtime.memoize.StampedCommonCache.getAndPut(StampedCommonCache.java:115) + at org.codehaus.groovy.transform.stc.AbstractExtensionMethodCache.get(AbstractExtensionMethodCache.java:51) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsForClassNode(StaticTypeCheckingSupport.java:309) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsForClassNode(StaticTypeCheckingSupport.java:296) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethodPointerExpression(StaticTypeCheckingVisitor.java:2405) + at org.codehaus.groovy.ast.expr.MethodPointerExpression.visit(MethodPointerExpression.java:55) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethodCallArguments(StaticTypeCheckingVisitor.java:2717) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethodCallExpression(StaticTypeCheckingVisitor.java:3335) + at org.codehaus.groovy.transform.sc.StaticCompilationVisitor.visitMethodCallExpression(StaticCompilationVisitor.java:411) + at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:77) + at org.codehaus.groovy.ast.CodeVisitorSupport.visitExpressionStatement(CodeVisitorSupport.java:117) + at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitExpressionStatement(ClassCodeVisitorSupport.java:252) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitExpressionStatement(StaticTypeCheckingVisitor.java:2118) + at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:40) + at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:86) + at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:216) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitBlockStatement(StaticTypeCheckingVisitor.java:3931) + at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:69) + at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:165) + at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:138) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitConstructorOrMethod(StaticTypeCheckingVisitor.java:2107) + at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:133) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.startMethodInference(StaticTypeCheckingVisitor.java:2539) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethod(StaticTypeCheckingVisitor.java:2497) + at org.codehaus.groovy.transform.sc.StaticCompilationVisitor.visitMethod(StaticCompilationVisitor.java:236) + at org.codehaus.groovy.ast.ClassNode.visitMethods(ClassNode.java:1164) + at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1157) + at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:56) + at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitClass(StaticTypeCheckingVisitor.java:406) + at org.codehaus.groovy.transform.sc.StaticCompilationVisitor.visitClass(StaticCompilationVisitor.java:194) + at org.codehaus.groovy.transform.sc.StaticCompileTransformation.visit(StaticCompileTransformation.java:65) + at org.codehaus.groovy.transform.ASTTransformationVisitor.visitClass(ASTTransformationVisitor.java:188) + at org.codehaus.groovy.transform.ASTTransformationVisitor.lambda$2(ASTTransformationVisitor.java:282) + at org.codehaus.groovy.control.CompilationUnit$IPrimaryClassNodeOperation.doPhaseOperation(CompilationUnit.java:980) + at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:689) + at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:651) + at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration.processToPhase(GroovyCompilationUnitDeclaration.java:225) + at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration.generateCode(GroovyCompilationUnitDeclaration.java:312) + at org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:925) + at org.eclipse.jdt.internal.compiler.Compiler.processCompiledUnits(Compiler.java:585) + at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:485) + at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:436) + at org.eclipse.jdt.internal.compiler.batch.Main.performCompilation(Main.java:4801) + at org.eclipse.jdt.internal.compiler.batch.Main.compile(Main.java:1801) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.jetbrains.jps.incremental.groovy.GreclipseBuilder.performCompilationInner(GreclipseBuilder.java:258) + at org.jetbrains.jps.incremental.groovy.GreclipseBuilder.performCompilation(GreclipseBuilder.java:215) + at org.jetbrains.jps.incremental.groovy.GreclipseBuilder.build(GreclipseBuilder.java:169) + at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1414) + at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:1092) + at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:1159) + at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:1053) + at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:882) + at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:449) + at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:190) + at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:138) + at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:297) + at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:130) + at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler.lambda$channelRead0$0(BuildMain.java:218) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:748) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +net.sf.jremoterun.utilities.nonjdk.log.JdkLoggerExtentionClass java.lang.ClassNotFoundException: net.sf.jremoterun.utilities.nonjdk.log.JdkLoggerExtentionClass + at com.intellij.util.lang.UrlClassLoader.findClass(UrlClassLoader.java:328) + at java.lang.ClassLoader.loadClass(ClassLoader.java:418) + at java.lang.ClassLoader.loadClass(ClassLoader.java:351) + at org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule.loadExtensionClass(MetaInfExtensionModule.java:88) + at org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule.newModule(MetaInfExtensionModule.java:73) + at org.codehaus.groovy.runtime.m12n.StandardPropertiesModuleFactory.newModule(StandardPropertiesModuleFactory.java:50) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanExtensionModuleFromProperties(ExtensionModuleScanner.java:86) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanExtensionModuleFromMetaInf(ExtensionModuleScanner.java:81) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanClasspathModulesFrom(ExtensionModuleScanner.java:63) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanClasspathModules(ExtensionModuleScanner.java:55) + at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.(MetaClassRegistryImpl.java:125) + at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.(MetaClassRegistryImpl.java:86) + at groovy.lang.GroovySystem.(GroovySystem.java:37) + at org.codehaus.groovy.runtime.InvokerHelper.(InvokerHelper.java:88) + at groovy.lang.GroovyObjectSupport.getDefaultMetaClass(GroovyObjectSupport.java:46) + at groovy.lang.GroovyObjectSupport.(GroovyObjectSupport.java:32) + at groovy.lang.Closure.(Closure.java:211) + at groovy.lang.Closure.(Closure.java:228) + at groovy.lang.Closure$1.(Closure.java:193) + at groovy.lang.Closure.(Closure.java:193) + at org.apache.groovy.parser.antlr4.util.StringUtils.replaceLineEscape(StringUtils.java:143) + at org.apache.groovy.parser.antlr4.util.StringUtils.replaceEscapes(StringUtils.java:133) + at org.apache.groovy.parser.antlr4.util.StringUtils.replaceEscapes(StringUtils.java:118) + at org.apache.groovy.parser.antlr4.AstBuilder.parseStringLiteral(AstBuilder.java:2664) + at org.apache.groovy.parser.antlr4.AstBuilder.visitStringLiteral(AstBuilder.java:2635) + at org.apache.groovy.parser.antlr4.AstBuilder.visitStringLiteral(AstBuilder.java:341) + at org.apache.groovy.parser.antlr4.GroovyParser$StringLiteralContext.accept(GroovyParser.java:12180) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:48) + at org.apache.groovy.parser.antlr4.GroovyParserBaseVisitor.visitStringLiteralAlt(GroovyParserBaseVisitor.java:130) + at org.apache.groovy.parser.antlr4.GroovyParser$StringLiteralAltContext.accept(GroovyParser.java:4137) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:48) + at org.apache.groovy.parser.antlr4.GroovyParserBaseVisitor.visitLiteralPrmrAlt(GroovyParserBaseVisitor.java:34) + at org.apache.groovy.parser.antlr4.GroovyParser$LiteralPrmrAltContext.accept(GroovyParser.java:10117) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:20) + at org.apache.groovy.parser.antlr4.AstBuilder.visit(AstBuilder.java:4218) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPathExpression(AstBuilder.java:2251) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPostfixExpression(AstBuilder.java:2733) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPostfixExpression(AstBuilder.java:341) + at org.apache.groovy.parser.antlr4.GroovyParser$PostfixExpressionContext.accept(GroovyParser.java:8092) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:48) + at org.apache.groovy.parser.antlr4.GroovyParserBaseVisitor.visitPostfixExprAlt(GroovyParserBaseVisitor.java:162) + at org.apache.groovy.parser.antlr4.GroovyParser$PostfixExprAltContext.accept(GroovyParser.java:8173) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:20) + at org.apache.groovy.parser.antlr4.AstBuilder.visit(AstBuilder.java:4218) + at org.apache.groovy.parser.antlr4.AstBuilder.visitExpressionListElement(AstBuilder.java:3397) + at org.apache.groovy.parser.antlr4.AstBuilder.visitEnhancedArgumentListElement(AstBuilder.java:2619) + at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) + at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) + at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) + at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) + at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) + at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) + at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) + at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485) + at org.apache.groovy.parser.antlr4.AstBuilder.visitEnhancedArgumentListInPar(AstBuilder.java:2556) + at org.apache.groovy.parser.antlr4.AstBuilder.visitArguments(AstBuilder.java:2542) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPathElement(AstBuilder.java:2340) + at org.apache.groovy.parser.antlr4.AstBuilder.lambda$createPathExpression$34(AstBuilder.java:4308) + at java.util.stream.ReduceOps$1ReducingSink.accept(ReduceOps.java:80) + at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) + at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) + at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) + at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) + at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) + at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) + at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:541) + at org.apache.groovy.parser.antlr4.AstBuilder.createPathExpression(AstBuilder.java:4304) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPathExpression(AstBuilder.java:2254) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPostfixExpression(AstBuilder.java:2733) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPostfixExpression(AstBuilder.java:341) + at org.apache.groovy.parser.antlr4.GroovyParser$PostfixExpressionContext.accept(GroovyParser.java:8092) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:48) + at org.apache.groovy.parser.antlr4.GroovyParserBaseVisitor.visitPostfixExprAlt(GroovyParserBaseVisitor.java:162) + at org.apache.groovy.parser.antlr4.GroovyParser$PostfixExprAltContext.accept(GroovyParser.java:8173) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:20) + at org.apache.groovy.parser.antlr4.AstBuilder.visit(AstBuilder.java:4218) + at org.apache.groovy.parser.antlr4.AstBuilder.visitCommandExpression(AstBuilder.java:2043) + at org.apache.groovy.parser.antlr4.AstBuilder.visitCommandExprAlt(AstBuilder.java:2028) + at org.apache.groovy.parser.antlr4.AstBuilder.visitCommandExprAlt(AstBuilder.java:341) + at org.apache.groovy.parser.antlr4.GroovyParser$CommandExprAltContext.accept(GroovyParser.java:8051) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:20) + at org.apache.groovy.parser.antlr4.AstBuilder.visit(AstBuilder.java:4218) + at org.apache.groovy.parser.antlr4.AstBuilder.visitEnhancedStatementExpression(AstBuilder.java:2234) + at org.apache.groovy.parser.antlr4.AstBuilder.visitVariableInitializer(AstBuilder.java:1984) + at org.apache.groovy.parser.antlr4.AstBuilder.visitVariableDeclarator(AstBuilder.java:1973) + at org.apache.groovy.parser.antlr4.AstBuilder.lambda$visitVariableDeclarators$17(AstBuilder.java:1946) + at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) + at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) + at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) + at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) + at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) + at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) + at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566) + at org.apache.groovy.parser.antlr4.AstBuilder.visitVariableDeclarators(AstBuilder.java:1949) + at org.apache.groovy.parser.antlr4.AstBuilder.visitVariableDeclaration(AstBuilder.java:1783) + at org.apache.groovy.parser.antlr4.AstBuilder.visitLocalVariableDeclaration(AstBuilder.java:1738) + at org.apache.groovy.parser.antlr4.AstBuilder.visitBlockStatement(AstBuilder.java:4013) + at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) + at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) + at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) + at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) + at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) + at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) + at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566) + at org.apache.groovy.parser.antlr4.AstBuilder.visitBlockStatements(AstBuilder.java:4006) + at org.apache.groovy.parser.antlr4.AstBuilder.visitBlockStatementsOpt(AstBuilder.java:3993) + at org.apache.groovy.parser.antlr4.AstBuilder.visitClosure(AstBuilder.java:3655) + at org.apache.groovy.parser.antlr4.AstBuilder.visitClosureOrLambdaExpression(AstBuilder.java:3981) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPathElement(AstBuilder.java:2404) + at org.apache.groovy.parser.antlr4.AstBuilder.lambda$createPathExpression$34(AstBuilder.java:4308) + at java.util.stream.ReduceOps$1ReducingSink.accept(ReduceOps.java:80) + at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) + at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) + at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) + at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) + at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) + at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) + at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:541) + at org.apache.groovy.parser.antlr4.AstBuilder.createPathExpression(AstBuilder.java:4304) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPathExpression(AstBuilder.java:2254) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPostfixExpression(AstBuilder.java:2733) + at org.apache.groovy.parser.antlr4.AstBuilder.visitPostfixExpression(AstBuilder.java:341) + at org.apache.groovy.parser.antlr4.GroovyParser$PostfixExpressionContext.accept(GroovyParser.java:8092) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:48) + at org.apache.groovy.parser.antlr4.GroovyParserBaseVisitor.visitPostfixExprAlt(GroovyParserBaseVisitor.java:162) + at org.apache.groovy.parser.antlr4.GroovyParser$PostfixExprAltContext.accept(GroovyParser.java:8173) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:20) + at org.apache.groovy.parser.antlr4.AstBuilder.visit(AstBuilder.java:4218) + at org.apache.groovy.parser.antlr4.AstBuilder.visitCommandExpression(AstBuilder.java:2043) + at org.apache.groovy.parser.antlr4.AstBuilder.visitCommandExprAlt(AstBuilder.java:2028) + at org.apache.groovy.parser.antlr4.AstBuilder.visitCommandExprAlt(AstBuilder.java:341) + at org.apache.groovy.parser.antlr4.GroovyParser$CommandExprAltContext.accept(GroovyParser.java:8051) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:20) + at org.apache.groovy.parser.antlr4.AstBuilder.visit(AstBuilder.java:4218) + at org.apache.groovy.parser.antlr4.AstBuilder.visitEnhancedStatementExpression(AstBuilder.java:2234) + at org.apache.groovy.parser.antlr4.AstBuilder.visitVariableInitializer(AstBuilder.java:1984) + at org.apache.groovy.parser.antlr4.AstBuilder.visitVariableDeclarator(AstBuilder.java:1973) + at org.apache.groovy.parser.antlr4.AstBuilder.lambda$visitVariableDeclarators$17(AstBuilder.java:1946) + at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) + at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) + at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) + at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) + at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) + at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) + at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566) + at org.apache.groovy.parser.antlr4.AstBuilder.visitVariableDeclarators(AstBuilder.java:1949) + at org.apache.groovy.parser.antlr4.AstBuilder.visitVariableDeclaration(AstBuilder.java:1783) + at org.apache.groovy.parser.antlr4.AstBuilder.visitLocalVariableDeclaration(AstBuilder.java:1738) + at org.apache.groovy.parser.antlr4.AstBuilder.visitBlockStatement(AstBuilder.java:4013) + at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) + at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) + at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) + at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) + at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) + at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) + at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566) + at org.apache.groovy.parser.antlr4.AstBuilder.visitBlockStatements(AstBuilder.java:4006) + at org.apache.groovy.parser.antlr4.AstBuilder.visitBlockStatementsOpt(AstBuilder.java:3993) + at org.apache.groovy.parser.antlr4.AstBuilder.visitBlock(AstBuilder.java:2022) + at org.apache.groovy.parser.antlr4.AstBuilder.visitMethodBody(AstBuilder.java:1733) + at org.apache.groovy.parser.antlr4.AstBuilder.visitMethodDeclaration(AstBuilder.java:1525) + at org.apache.groovy.parser.antlr4.AstBuilder.visitMemberDeclaration(AstBuilder.java:1411) + at org.apache.groovy.parser.antlr4.AstBuilder.visitClassBodyDeclaration(AstBuilder.java:1387) + at org.apache.groovy.parser.antlr4.AstBuilder.lambda$visitClassBody$9(AstBuilder.java:1260) + at java.util.ArrayList.forEach(ArrayList.java:1257) + at org.apache.groovy.parser.antlr4.AstBuilder.visitClassBody(AstBuilder.java:1258) + at org.apache.groovy.parser.antlr4.AstBuilder.visitClassDeclaration(AstBuilder.java:1216) + at org.apache.groovy.parser.antlr4.AstBuilder.visitTypeDeclaration(AstBuilder.java:1056) + at org.apache.groovy.parser.antlr4.AstBuilder.visitTypeDeclaration(AstBuilder.java:341) + at org.apache.groovy.parser.antlr4.GroovyParser$TypeDeclarationContext.accept(GroovyParser.java:678) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:48) + at org.apache.groovy.parser.antlr4.GroovyParserBaseVisitor.visitScriptStatement(GroovyParserBaseVisitor.java:466) + at org.apache.groovy.parser.antlr4.GroovyParser$ScriptStatementContext.accept(GroovyParser.java:471) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:20) + at org.apache.groovy.parser.antlr4.AstBuilder.visit(AstBuilder.java:4218) + at org.apache.groovy.parser.antlr4.AstBuilder.lambda$visitScriptStatements$0(AstBuilder.java:476) + at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) + at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) + at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) + at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) + at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) + at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) + at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566) + at org.apache.groovy.parser.antlr4.AstBuilder.visitScriptStatements(AstBuilder.java:477) + at org.apache.groovy.parser.antlr4.AstBuilder.visitCompilationUnit(AstBuilder.java:434) + at org.apache.groovy.parser.antlr4.AstBuilder.visitCompilationUnit(AstBuilder.java:341) + at org.apache.groovy.parser.antlr4.GroovyParser$CompilationUnitContext.accept(GroovyParser.java:317) + at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:20) + at org.apache.groovy.parser.antlr4.AstBuilder.visit(AstBuilder.java:4218) + at org.apache.groovy.parser.antlr4.AstBuilder.buildAST(AstBuilder.java:424) + at org.apache.groovy.parser.antlr4.Antlr4ParserPlugin.buildAST(Antlr4ParserPlugin.java:58) + at org.codehaus.groovy.control.SourceUnit.buildAST(SourceUnit.java:257) + at java.util.Iterator.forEachRemaining(Iterator.java:116) + at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) + at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:647) + at org.codehaus.groovy.control.CompilationUnit.buildASTs(CompilationUnit.java:666) + at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:632) + at org.jetbrains.groovy.compiler.rt.GroovyCompilerWrapper.compile(GroovyCompilerWrapper.java:62) + at org.jetbrains.groovy.compiler.rt.DependentGroovycRunner.runGroovyc(DependentGroovycRunner.java:119) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.jetbrains.groovy.compiler.rt.GroovycRunner.intMain2(GroovycRunner.java:81) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.jetbrains.jps.incremental.groovy.InProcessGroovyc.runGroovycInThisProcess(InProcessGroovyc.java:167) + at org.jetbrains.jps.incremental.groovy.InProcessGroovyc.lambda$runGroovyc$0(InProcessGroovyc.java:77) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:748) + + + */ \ No newline at end of file diff --git a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner34.groovy b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner34.groovy index 107c77e9..db79e47b 100644 --- a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner34.groovy +++ b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/IdeaBRunner34.groovy @@ -3,7 +3,10 @@ package net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild2 import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.nonjdk.PidDetector +import net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.IdeaBuildRunnerSettings +import net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.IdeaBuilderAddGroovyRuntime import net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.LauncherImpl +import org.jetbrains.jps.cmdline.LauncherOriginal import java.lang.management.ManagementFactory import java.util.logging.Logger @@ -12,6 +15,7 @@ import java.util.logging.Logger class IdeaBRunner34 implements Runnable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static boolean launcherOriginal = true static void f1() { @@ -24,12 +28,29 @@ class IdeaBRunner34 implements Runnable { } static void f2() { - String[] args = LauncherImpl.argsP + String[] args = IdeaBuildRunnerSettings.argsPv2.toArray(new String[0]) int pid = PidDetector.detectPid() log.info "running, pid = ${pid} , ${new Date()}, " - log.info "running ${args} " + log.info "running args : ${args} " List inputArguments = ManagementFactory.getRuntimeMXBean().getInputArguments() log.info "inputArguments = ${inputArguments}" + long delay = System.currentTimeMillis() - IdeaBuildRunnerSettings.startDate.getTime() + log.info "startup delay : ${delay / 1000} s" + if(IdeaBuildRunnerSettings.beforeMainOriginalRun!=null){ + IdeaBuildRunnerSettings.beforeMainOriginalRun.run() + } + if(launcherOriginal){ + LauncherOriginal.main(args) + }else{ + f3(args) + } + //IdeaBuildRunnerSettings.afterMainOriginalRun.run() + +// mainMethod.invoke(null, new Object[] {jpsArgs}); + } + + static void f3( String[] args ){ + IdeaBuildRunnerSettings.originalTried = true; final String jpsClasspath = args[0]; final String mainClassName = args[1]; final String[] jpsArgs = new String[args.length - 2]; @@ -41,7 +62,8 @@ class IdeaBRunner34 implements Runnable { final String path = tokenizer.nextToken(); urls.add(new File(path).toURI().toURL()); } - final URLClassLoader jpsLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), LauncherImpl.getClassLoader()); + URL[] urlsArray = urls.toArray(new URL[urls.size()]) as URL[]; + final URLClassLoader jpsLoader = new URLClassLoader(urlsArray, LauncherImpl.getClassLoader()); // final GroovyClassLoader jpsLoader = JrrClassUtils.currentClassLoader as GroovyClassLoader; // urls.each { // jpsLoader.addURL(it) @@ -54,11 +76,11 @@ class IdeaBRunner34 implements Runnable { System.setProperty("io.netty.serviceThreadPrefix", "Netty"); //} + final Class mainClass = jpsLoader.loadClass(mainClassName); Thread.currentThread().setContextClassLoader(jpsLoader); JrrClassUtils.runMainMethod(mainClass, jpsArgs) -// mainMethod.invoke(null, new Object[] {jpsArgs}); } @Override diff --git a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/Redirector.groovy b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/Redirector.groovy index 6df7c190..e3190200 100644 --- a/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/Redirector.groovy +++ b/src-idea-launcher2/net/sf/jremoterun/utilities/nonjdk/idea/laumcherbuild2/Redirector.groovy @@ -4,6 +4,8 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.nonjdk.ConsoleRedirect import net.sf.jremoterun.utilities.nonjdk.LogExitTimeHook +import net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.IdeaBuildRunnerSettings +import net.sf.jremoterun.utilities.nonjdk.idea.laumcherbuild.IdeaBuilderAddGroovyRuntime import java.util.logging.Logger @@ -20,8 +22,11 @@ class Redirector implements Runnable { } void f1() { + if(IdeaBuildRunnerSettings.outputFile!=null){ + ConsoleRedirect.setOutputWithRotationAndFormatter(IdeaBuildRunnerSettings.outputFile, 95) + } // File f = "c:\\1\\3\\idea_b_logs\\a.log" as File -// ConsoleRedirect.setOutputWithRotationAndFormatter(f, 95) + LogExitTimeHook.addShutDownHook() } } diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/IndexReadyListener.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/IndexReadyListener.groovy index 9ffc9c83..27afb7a5 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/IndexReadyListener.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/IndexReadyListener.groovy @@ -1,15 +1,20 @@ package idea.plugins.thirdparty.filecompletion.jrr +import com.intellij.diagnostic.LoadingState +import com.intellij.diagnostic.StartUpMeasurer import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.Project import com.intellij.openapi.project.ProjectManager import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.ContextClassLoaderWrapper import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.nonjdk.Scheduler import javax.swing.SwingUtilities import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicReference +import java.util.logging.Level import java.util.logging.Logger @CompileStatic @@ -23,6 +28,10 @@ class IndexReadyListener { public static volatile projectOpened = false public static volatile indexReady = false public static volatile runnerInProgress = false + public static ClassLoader classLoaderWrap = JrrClassUtils.getCurrentClassLoader(); + + public static int maxCount2 = 20; + public static long sleepTime2 = 10_000; static void addListenerAfterProjectOpened(Runnable r) { @@ -36,6 +45,28 @@ class IndexReadyListener { listenersAfterIndexReady.add(r) } + static void runListenersWhenReady2() { + if (runnerInProgress) { + + } else { + try { + Runnable r = { + try { + check2() + } catch (Throwable e) { + JrrUtilities.showException("failed run", e) + } + } + Thread thread = new Thread(r, "Open idea waiter2") + thread.setContextClassLoader(classLoaderWrap); + thread.start() + } catch (Throwable e) { + JrrUtilities.showException("failed run", e) + } + + } + } + static void runListenersWhenReady() { if (runnerInProgress) { @@ -47,10 +78,12 @@ class IndexReadyListener { try { check1() } catch (Throwable e) { + log.log(Level.SEVERE,"failed run", e) JrrUtilities.showException("failed run", e) } } Thread thread = new Thread(r, "Open idea waiter") + thread.setContextClassLoader(classLoaderWrap); thread.start() } catch (Throwable e) { JrrUtilities.showException("failed run", e) @@ -59,13 +92,19 @@ class IndexReadyListener { } } - static int maxCount = 10 + + public static int maxCount1 = 10; + + public static Runnable waitTimeout1 = { + JrrUtilities.showException("no one project still opened 1",new Exception("no one project still opened at ${new Date()}")); + }; static void check1() { - int i = maxCount + int i = maxCount1 while (i > 0) { - log.info "check ${i}" - if (isAtLeastOneProjectOpened()) { + boolean projectOpened =isAtLeastOneProjectOpened() + log.info "check ${i} projectOpened = ${projectOpened}" + if (projectOpened) { SwingUtilities.invokeLater { try { List l2 = new ArrayList<>(listenersAfterProjectOpened) @@ -81,10 +120,37 @@ class IndexReadyListener { Thread.sleep(30_000) i--; } - log.info "no one prject still opened at ${new Date()}" + log.info "no one prject still opened 1 at ${new Date()}" + waitTimeout1.run() + } + + + + public static Runnable waitTimeout2 = { + JrrUtilities.showException("no one project still opened 2",new Exception("no one project still opened at ${new Date()}")); + }; + + static void check2() { + final AtomicReference state = JrrClassUtils.getFieldValue(StartUpMeasurer,'currentState') as AtomicReference + int i = maxCount2 + while (i > 0) { + + LoadingState state1 = state.get() + log.info "check2 ${i} current state = ${state1}" + if( state1!=null && state1.ordinal() >= LoadingState.APP_STARTED.ordinal()){ + log.info "app started ${state1}" + runListenersWhenReady() + return + } + Thread.sleep(sleepTime2) + i--; + } + log.info "no one project still opened 2 at ${new Date()}" + waitTimeout2.run() } + static void runListeners3(List listeners) { listeners = new ArrayList<>(listeners); if (listeners.size() == 0) { @@ -94,10 +160,10 @@ class IndexReadyListener { listeners.remove(0) SwingUtilities.invokeLater { try { - first.run(); + ContextClassLoaderWrapper.wrap2(classLoaderWrap,first) runListeners3(listeners) } catch (Throwable e) { - JrrUtilities.showException("failed run ${it}", e) + JrrUtilities.showException("failed run ${first}", e) } } } diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/InitPlugin.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/InitPlugin.groovy index 261eb43b..f0693c7d 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/InitPlugin.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/InitPlugin.groovy @@ -17,6 +17,8 @@ class InitPlugin { public static boolean inited = false; + public static OSIntegrationIdea osIntegrationIdea + static void init() { if(inited){ @@ -31,7 +33,8 @@ class InitPlugin { Log4jConfigurator.setLevelForLogger1(logger.name, Level.DEBUG) CompetionContributerRenew.regDocumentation() CompetionContributerRenew.regGotto() - MBeanFromJavaBean.registerMBean(new OSIntegrationIdea()); + osIntegrationIdea= new OSIntegrationIdea() + MBeanFromJavaBean.registerMBean(osIntegrationIdea); } diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/InitPlugin2.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/InitPlugin2.groovy index a6fd654c..cb3c6d1d 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/InitPlugin2.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/InitPlugin2.groovy @@ -2,6 +2,7 @@ package idea.plugins.thirdparty.filecompletion.jrr import groovy.transform.CompileStatic import idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.IdeaLibManagerSwing +import idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.IdeaRuntimeClassRefrences import idea.plugins.thirdparty.filecompletion.share.Ideasettings.IdeaJavaRunner2Settings import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities @@ -17,7 +18,7 @@ class InitPlugin2 { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); - public static boolean inited = false; + public static volatile boolean inited = false; static boolean init() { if (inited) { @@ -33,6 +34,7 @@ class InitPlugin2 { try { initImpl2() } catch (Throwable e) { + log.error("Failed init idea", e) JrrUtilities.showException("Failed init idea", e) } } @@ -47,11 +49,17 @@ class InitPlugin2 { IvyDepResolver2.setDepResolver() } IndexReadyListener.listenersAfterProjectOpened.add { - log.info "creating IdeaLibManagerSwing .." - IdeaLibManagerSwing.createIdeaPanel12(); - log.info "created IdeaLibManagerSwing" + try { + log.info "creating IdeaLibManagerSwing .." + IdeaLibManagerSwing.createIdeaPanel12(); + log.info "created IdeaLibManagerSwing" + }catch(Throwable e){ + log.error("Failed init idea", e) + JrrUtilities.showException("Failed init idea", e) + } } - IndexReadyListener.runListenersWhenReady() + IdeaRuntimeClassRefrences.addReferences() + IndexReadyListener.runListenersWhenReady2() } diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/MyCompletionContributorImpl.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/MyCompletionContributorImpl.groovy index fa173995..f73daf38 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/MyCompletionContributorImpl.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/MyCompletionContributorImpl.groovy @@ -7,7 +7,6 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import org.apache.log4j.LogManager import org.apache.log4j.Logger -import org.jetbrains.annotations.NotNull /** * Reserved for future flexibility @@ -18,6 +17,6 @@ class MyCompletionContributorImpl extends CompletionContributor { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); @Override - public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) { + public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) { } } diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/CompletionProviderCommon.java b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/CompletionProviderCommon.java new file mode 100644 index 00000000..7ba0dbe2 --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/CompletionProviderCommon.java @@ -0,0 +1,14 @@ +package idea.plugins.thirdparty.filecompletion.jrr.a.actions; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; + +public class CompletionProviderCommon extends CompletionProvider { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet result) { + + } +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/ReloadClassActionImpl.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/ReloadClassActionImpl.groovy index 70079dc3..49e42eed 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/ReloadClassActionImpl.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/ReloadClassActionImpl.groovy @@ -13,20 +13,25 @@ import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiFile import com.intellij.psi.PsiJavaFile import groovy.transform.CompileStatic +import idea.plugins.thirdparty.filecompletion.jrr.a.actions.reloadclass.ReloadClassSettingsI import idea.plugins.thirdparty.filecompletion.share.OSIntegrationIdea +import net.sf.jremoterun.JrrUtils import net.sf.jremoterun.SimpleJvmTiAgent import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities -import net.sf.jremoterun.utilities.javassist.JrrJavassistUtils import org.apache.log4j.LogManager import org.apache.log4j.Logger import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl +import javax.swing.JOptionPane + @CompileStatic public class ReloadClassActionImpl extends AnAction { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); + public static ReloadClassSettingsI reloadClassSettings; + @Override public void actionPerformed(AnActionEvent anActionEvent) { try { @@ -74,11 +79,19 @@ public class ReloadClassActionImpl extends AnAction { Document document = FileEditorManager.getInstance(openedProject).getSelectedTextEditor().getDocument(); PsiFile psiFile1 = psiDocumentManager.getPsiFile(document); String className = findClassName(psiFile1); - log.debug("class name 2 : " + className); + //log.debug("class name 2 : " + className); + + if (className == null) { + + } else { + if (reloadClassSettings==null) { + throw new Exception("reloadClassSettings was not set") + } + reloadClassSettings.receiveConnection().redefineClassAndAnonClasses(className,reloadClassSettings.getClassLoaderId() ); + JOptionPane.showMessageDialog(null, "Class reloaded : ${className}") +// Class clazz = ReloadClassActionImpl.getClassLoader().loadClass(className); +// JrrJavassistUtils.reloadClassAndAnonClasses(clazz); - if (className != null) { - Class clazz = ReloadClassActionImpl.getClassLoader().loadClass(className); - JrrJavassistUtils.reloadClassAndAnonClasses(clazz); } //JnaBean.jnaBean.reloadClassAndAnonClasses(clazz); @@ -89,8 +102,8 @@ public class ReloadClassActionImpl extends AnAction { try { startActionImpl2() } catch (Exception e) { - log.debug('', e); - JrrUtilities.showException("Class reload", e); + log.debug('failed reload class', e); + JrrUtilities.showException("Class reload", JrrUtils.getRootException(e) ); } log.debug("action started"); } diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/RemoteRunActionImpl.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/RemoteRunActionImpl.groovy index d7969aa1..90517dff 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/RemoteRunActionImpl.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/RemoteRunActionImpl.groovy @@ -28,6 +28,8 @@ import org.apache.log4j.Logger import org.jetbrains.annotations.Nullable import org.jetbrains.plugins.groovy.GroovyFileType +import java.text.SimpleDateFormat + @CompileStatic class RemoteRunActionImpl extends AnAction { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); @@ -64,7 +66,7 @@ class RemoteRunActionImpl extends AnAction { final File file = new File( userHome, "jrr.properties"); file.text = """ -# generated at ${new Date().format("yyyy-MM-dd HH:mm")} +# generated at ${new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date())} className=${clazz.qualifiedName} methodName=${psiMethod.name} lineNumer=${lineNumber + 2} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/openfile/IdeaOpenFileUtils.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/openfile/IdeaOpenFileUtils.groovy index 556385a2..c86f58e6 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/openfile/IdeaOpenFileUtils.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/openfile/IdeaOpenFileUtils.groovy @@ -131,9 +131,10 @@ class IdeaOpenFileUtils { return null } log.debug "cp 1" - if (psiElement.parent instanceof GrReferenceExpression) { + PsiElement parent3 = psiElement.parent + if (parent3 instanceof GrReferenceExpression) { log.debug "cp 2" - GrReferenceExpression e = (GrReferenceExpression) psiElement.parent; + GrReferenceExpression e = (GrReferenceExpression) parent3; PsiType type = e.type; if (type instanceof PsiClassType) { log.debug "cp 3" @@ -155,8 +156,8 @@ class IdeaOpenFileUtils { } return null } else { - File file1 = MyAcceptFileProviderImpl.findFileFromVarGeneric(psiElement.parent) - log.debug "found : ${file1} ${psiElement.parent}" + File file1 = MyAcceptFileProviderImpl.findFileFromVarGeneric(parent3) + log.debug "found : ${file1} ${parent3}" return file1 } diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/JmxLocalhostConnections.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/JmxLocalhostConnections.groovy new file mode 100644 index 00000000..b77830f2 --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/JmxLocalhostConnections.groovy @@ -0,0 +1,12 @@ +package idea.plugins.thirdparty.filecompletion.jrr.a.actions.reloadclass + +import groovy.transform.CompileStatic; + +@CompileStatic +interface JmxLocalhostConnections { + + String name(); + + int getPort(); + +} \ No newline at end of file diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/ReloadClassConnectionPanel.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/ReloadClassConnectionPanel.groovy new file mode 100644 index 00000000..31fe3d49 --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/ReloadClassConnectionPanel.groovy @@ -0,0 +1,146 @@ +package idea.plugins.thirdparty.filecompletion.jrr.a.actions.reloadclass + +import groovy.transform.CompileStatic +import idea.plugins.thirdparty.filecompletion.jrr.a.actions.ReloadClassActionImpl; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.jmx.MbeanConnectionCreatorCache +import net.sf.jremoterun.utilities.nonjdk.redefineclass.RedefineClassI +import net.sf.jremoterun.utilities.nonjdk.redefineclass.RedefineClassImpl +import net.sf.jremoterun.utilities.nonjdk.swing.JPanel4FlowLayout +import net.sf.jremoterun.utilities.nonjdk.swing.NameAndTextField + +import javax.swing.AbstractButton +import javax.swing.ButtonGroup +import javax.swing.ButtonModel +import javax.swing.JPanel +import javax.swing.JRadioButton +import java.awt.event.ActionEvent +import java.awt.event.ActionListener; +import java.util.logging.Logger; + +@CompileStatic +class ReloadClassConnectionPanel implements ReloadClassSettingsI { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static String ideaSelfButtonName = 'Idea self' + public static String hostAndPortButtonName = 'Remote jmx' + + public JPanel panel = new JPanel4FlowLayout(); + public ButtonGroup btns = new ButtonGroup(); + public JRadioButton ideaButton = new JRadioButton(ideaSelfButtonName) + public JRadioButton hostAndPortButton = new JRadioButton(hostAndPortButtonName) + public NameAndTextField hostAndPortTextField = new NameAndTextField('Host&port', ' 127.0.0.1 : ', 70) + public NameAndTextField classLoaderId = new NameAndTextField('Classloader id', ' ', 20) + + public Map map = [:]; + public ActionListener al = new ActionListener() { + @Override + void actionPerformed(ActionEvent e) { + JRadioButton source = e.getSource() as JRadioButton; + onActionListener(source) + } + } + + ReloadClassConnectionPanel() { + init() + } + + static ReloadClassConnectionPanel createAndSet(){ + ReloadClassConnectionPanel panel3 = new ReloadClassConnectionPanel(); + panel3.createFooter() + ReloadClassActionImpl.reloadClassSettings = panel3; + return panel3 + } + + void onActionListener(JRadioButton source) { + String text = source.getText(); + boolean enableT = text == hostAndPortButtonName + hostAndPortTextField.setEnabled(enableT); + } + + void init() { + ideaButton = addToMap(ideaSelfButtonName, 'some') + ideaButton.setSelected(true); + } + + void createFooter(){ + hostAndPortButton = addToMap(hostAndPortButtonName, 'some') + panel.add(hostAndPortButton) + panel.add(hostAndPortTextField) + panel.add(classLoaderId) + hostAndPortTextField.setEnabled(false) + } + + void addJmxLocalhostConnections(List connections) { + connections.each { + addToMap(it.name(), it) + } + } + + JRadioButton addToMap(String name, Object handle) { + JRadioButton b = new JRadioButton(name) + Object put = map.put(name, handle); + if (put != null) { + throw new Exception("already contains ${name} before : ${put}, new : ${handle}") + } + b.addActionListener(al) + btns.add(b); + panel.add(b) + return b; + } + + @Override + RedefineClassI receiveConnection() { + JRadioButton selectedButton = findSelectedButton(); + String text = selectedButton.getText(); + RedefineClassI connectionDefault = receiveConnectionDefault(text) + if (connectionDefault == null) { + throw new Exception("failed map : ${text}") + } + return connectionDefault + } + + @Override + String getClassLoaderId() { + String s = classLoaderId.getText() + if (s == null) { + return RedefineClassI.thisClassCl + } + s = s.trim(); + if (s.length() == 0) { + return RedefineClassI.thisClassCl + } + return s; + } + + + RedefineClassI receiveConnectionDefault(String text) { + if (text == ideaSelfButtonName) { + return RedefineClassImpl.defaultInstance; + } + if (text == hostAndPortButtonName) { + String text1 = hostAndPortTextField.getText(); + List tokenize = text1.tokenize(':') + String host = tokenize.get(0).trim() + int port = Integer.parseInt(tokenize.get(1).trim()) + return MbeanConnectionCreatorCache.getClient(RedefineClassI, host, port, RedefineClassI.objectName) + } + Object handle = map.get(text) + if (handle instanceof JmxLocalhostConnections) { + JmxLocalhostConnections localhostConnection = (JmxLocalhostConnections) handle; + return MbeanConnectionCreatorCache.getClient(RedefineClassI, '127.0.0.1', localhostConnection.port, RedefineClassI.objectName) + } + return null; + } + + JRadioButton findSelectedButton() { + List buttons = btns.getElements().toList() + List buttons2 = buttons as List; + JRadioButton selectedButton = buttons2.find { it.isSelected() } + if (selectedButton == null) { + throw new Exception("No button selected") + } + return selectedButton; + } + +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/ReloadClassSettingsI.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/ReloadClassSettingsI.groovy new file mode 100644 index 00000000..f413a872 --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/actions/reloadclass/ReloadClassSettingsI.groovy @@ -0,0 +1,16 @@ +package idea.plugins.thirdparty.filecompletion.jrr.a.actions.reloadclass + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.redefineclass.RedefineClassI; + +import java.util.logging.Logger; + +@CompileStatic +interface ReloadClassSettingsI { + + RedefineClassI receiveConnection(); + + String getClassLoaderId(); + +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/charset/CharsetCompletionProviderImpl.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/charset/CharsetCompletionProviderImpl.groovy index ecf25bac..ca5f26c1 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/charset/CharsetCompletionProviderImpl.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/charset/CharsetCompletionProviderImpl.groovy @@ -11,6 +11,7 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.util.ProcessingContext import groovy.transform.CompileStatic import idea.plugins.thirdparty.filecompletion.jrr.IdeaMagic +import idea.plugins.thirdparty.filecompletion.jrr.a.actions.CompletionProviderCommon import idea.plugins.thirdparty.filecompletion.jrr.a.file.MyAcceptFileProviderImpl import idea.plugins.thirdparty.filecompletion.jrr.a.javassist.JavassistCompletionBean import idea.plugins.thirdparty.filecompletion.share.OSIntegrationIdea @@ -23,18 +24,20 @@ import javax.swing.* import java.nio.charset.Charset @CompileStatic -public class CharsetCompletionProviderImpl extends CompletionProvider { +public class CharsetCompletionProviderImpl extends CompletionProviderCommon { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); static Icon timeZoneIcon = IconLoader.getIcon('/icons/time_zone.png', OSIntegrationIdea); //static Map timeZones = Charset.availableCharsets(); - static List charsets = (List)Charset.availableCharsets().values().collect {it.aliases()}.flatten(); + static List charsets = (List) Charset.availableCharsets().values().collect { it.aliases() }.flatten(); - @Override - protected void addCompletions( - @NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet result) { + + + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet result) { PsiElement psiElement = parameters.position; if (!(psiElement instanceof LeafPsiElement)) { return; @@ -45,9 +48,8 @@ public class CharsetCompletionProviderImpl extends CompletionProvider { +public class FileCompletionProviderImpl extends CompletionProviderCommon { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); @@ -31,7 +31,7 @@ public class FileCompletionProviderImpl extends CompletionProvider { - - // this is log file - public static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); - - - @Override - boolean accepts(@Nullable Object o) { - log.debug " accept : ${o?.class.name}" - if (o instanceof LeafPsiElement) { - JrrIdeaBean.bean.psiElement2 = (PsiElement) o; - boolean accept = isOkJavaAndGroovyPsiElement(o) != null; - return accept; - } - return false; - // - } - - static File isOkJavaPsiElement3(PsiJavaToken leafPsiElement) { - PsiElement parent = leafPsiElement.parent.parent.parent - if (!(parent instanceof PsiNewExpression)) { - log.debug("not new expression") - return null; - } -// PsiNewExpression newExpression = (PsiNewExpression) parent - log.debug "${parent}" - return javaFileViaNewExpression7(parent, true); - } - - static FileCompletionBean isOkJavaPsiElement(PsiJavaToken leafPsiElement, boolean addSuffix) { - PsiElement parent = leafPsiElement.parent.parent.parent - if (!(parent instanceof PsiNewExpression)) { - log.debug("not new expression") - return null; - } -// PsiNewExpression newExpression = (PsiNewExpression) parent - log.debug "${parent}" - PsiNewExpression pn = parent - TwoResult res3 = javaFileViaNewExpression3(pn, addSuffix); - if (res3 == null) { - return null - } - PsiExpression[] argsExpressions = pn.argumentList.expressions - PsiExpression element = argsExpressions.toList().last() - String value2 = getStringFromPsiLiteral(element); - if (value2 == null) { - log.debug "not a string" - return null; - } - FileCompletionBean fileCompletionBean = new FileCompletionBean() - fileCompletionBean.wholeFileDeclaration = parent - fileCompletionBean.value = value2 - fileCompletionBean.parentFilePath = res3.second - return fileCompletionBean - - } - - static FileCompletionBean isOkJavaAndGroovyPsiElement(LeafPsiElement leafPsiElement) { - if (leafPsiElement instanceof PsiJavaTokenImpl) { - return isOkJavaPsiElement(leafPsiElement, false) - } - PsiElement parent = leafPsiElement.getParent(); - if (!(parent instanceof PsiLiteral)) { - return null; - } - Object value = parent.getValue(); - if (!(value instanceof String)) { - return null; - } - FileCompletionBean completionBean = new FileCompletionBean(); - completionBean.value = getStringFromPsiLiteral(parent) - if (completionBean.value == null) { - return null; - } - // log.debug "value = ${completionBean.value}" - completionBean.literalElemtnt = parent; - PsiElement parent1 = parent.parent; - PsiElement parent2 = parent1.parent - if (parent1 instanceof GrArgumentList) { - if (parent2 instanceof GrNewExpression) { - TwoResult res = fileViaGrNewExpression(parent2) - if (res != null && res.first) { - completionBean.wholeFileDeclaration = parent2 - completionBean.parentFilePath = res.second - return completionBean - } - return null - } - } - if (parent1 instanceof GrSafeCastExpression) { - File file = resolveFileFromSafeCast(parent1) - if (file != null) { - completionBean.wholeFileDeclaration = parent1 - return completionBean - } - - } -// log.info "cp 1 : ${parent1.class.name} ${parent1}" - if (parent2 instanceof GrMethodCallExpression) { - File file = fileViaFileChildMethod(parent2, false) -// log.info "cp 2 : ${file}" - if (file != null) { - completionBean.wholeFileDeclaration = parent1 - completionBean.parentFilePath = file - return completionBean - } - - } - - return null; - } - - /** - * Calculate path for var. - * Example : File parent = new File('/opt'); - * use parent somewhere. This method calc path for parent var - */ - static File findFileFromVarGeneric(PsiElement varRef) { - if (varRef == null) { - log.warn("ref is null", new Exception()) - return null - } - if (varRef instanceof GrReferenceExpression) { - // may be use resolve ? - // varRef.resolve() - GroovyResolveResult[] variants = varRef.getSameNameVariants() - if (variants == null) { - log.debug "variants is null" - return null - } - if (variants.length != 1) { - log.debug "args not 1" - return null - } - PsiElement element = variants[0].element - if (element == null) { - log.debug "failed resolve el var for ${varRef}" - return null - } - if (element == varRef) { - log.info "cycle ${varRef}" - return null - } - return findFileFromVarGeneric(element) - } - if (varRef instanceof PsiReferenceExpression) { - PsiElement resolve = varRef.resolve() - if (resolve == null) { - log.info "failed resolve ${varRef}" - return null - } - if (resolve == varRef) { - log.info "cycle : ${varRef}" - return null - } - return findFileFromVarGeneric(resolve) - } - if (varRef instanceof GrField) { - GrExpression gr1 = varRef.initializerGroovy - if (gr1 == null) { - log.debug "null init for ${varRef}" - return null - } - return findFileFromVarGeneric(gr1) - } - if (varRef instanceof PsiField) { - return javaFindFileFromField(varRef) - } - if (varRef instanceof GrVariable) { - GrExpression gr1 = varRef.initializerGroovy - if (gr1 == null) { - log.debug "null init for ${varRef}" - return null - } - return findFileFromVarGeneric(gr1) - } - if (varRef instanceof GrAccessorMethod) { - PsiElement navigationElement = varRef.navigationElement - if (navigationElement == null) { - log.info "navigation el is null" - } else { - if (navigationElement != varRef) { - return findFileFromVarGeneric(navigationElement) - } - } - } - - // new begin - if (varRef instanceof GrSafeCastExpression) { - return resolveFileFromSafeCast(varRef) - } - if (varRef instanceof GrNewExpression) { - return fileViaGroovyNewExpression3(varRef, true); - } - if (varRef instanceof GrMethodCallExpression) { - return fileViaFileChildMethod(varRef, true); - } - if (varRef instanceof PsiNewExpression) { - javaFileViaNewExpression7(varRef, true) - } - // new end - - log.debug "not a GrVar : ${varRef.class} ${varRef}" - return null; - - } - -// private static File findFileFromGrExpressionCommon(GrExpression initializerGroovy) { -// log.debug "not a new expression" -// return null; -//// log.debug "varRef no ${varRef.class.name} ${varRef}" -// -// } - - - static String getStringFromPsiLiteral(PsiElement psiElement) { - if (!(psiElement instanceof PsiLiteral)) { - return null; - } - PsiLiteral literalElemtnt = (PsiLiteral) psiElement; - Object value = literalElemtnt.getValue(); - if (!(value instanceof String)) { - return null; - } - return value.replace(IdeaMagic.addedConstant, ''); - } - - - private static File resolveFileFromSafeCast(GrSafeCastExpression castExpression) { - String text = castExpression.type.presentableText - if (text != null && text.contains('File')) { - log.debug("accpted") - String literal = getStringFromPsiLiteral(castExpression.operand) - if (literal == null) { - log.debug "not a tsring" - return null; - } - return new File(literal); - } - return null - } - - /** - * Internal method - */ - private - static TwoResult fileViaGrNewExpression(GrNewExpression grExpression) { - PsiType type = grExpression.type; - if (!(type instanceof GrClassReferenceType)) { - return null - } - PsiClass resolve = type.resolve() - - if (resolve == null || !(resolve.name.contains('File'))) { - log.debug("accpted") - return null - } - if (grExpression.argumentList.allArguments.length == 1) { - String literal = getStringFromPsiLiteral(grExpression.argumentList.allArguments[0]); - if (literal == null) { - log.debug "not a string" - return null - } - return new TwoResult(true, null); - } - if (grExpression.argumentList.allArguments.length == 2) { - File parentFilePath = fileViaGroovyNewExpression3(grExpression, false) - if (parentFilePath == null) { - return null - } - return new TwoResult(true, parentFilePath); -// return completionBean.parentFilePath != null; - } - return null - } - - /** - * Resolve java construction new File('path') - * java construction not supported : new File(parent,'child') - * but for groovy supported - * @param grExpression - * @param addSuffix - * @return - */ - private - static TwoResult javaFileViaNewExpression3(PsiNewExpression grExpression, boolean addSuffix) { - PsiType type = grExpression.type; - if (!(type instanceof PsiClassType)) { - log.debug "not a type" - return null; - } - PsiClass psiClass = type.resolve(); - if (psiClass == null || psiClass.name == null || !(psiClass.name.contains('File'))) { - log.debug "not a file" - return null; - } - PsiExpression[] argsExpressions = grExpression.argumentList.expressions - if (argsExpressions.length == 1) { -// FileCompletionBean fileCompletionBean = new FileCompletionBean() -// fileCompletionBean.value = value2 - return new TwoResult(true, null); - } - if (argsExpressions.length == 2) { - log.debug "too many args" - File fff = javaFileViaNewExpression7(grExpression, addSuffix) - if (fff == null) { - return null; - } - return new TwoResult(true, fff); - - - } - log.debug "not implemented" - return null - } - - private static File javaFileViaNewExpression7(PsiNewExpression grExpression, boolean addSuffix) { - PsiType type = grExpression.type; - if (!(type instanceof PsiClassType)) { - log.debug "not a type" - return null; - } - PsiClass psiClass = type.resolve(); - if (psiClass == null || psiClass.name == null || !(psiClass.name.contains('File'))) { - log.debug "not a file" - return null; - } - PsiExpression[] argsExpressions = grExpression.argumentList.expressions - if (argsExpressions.length == 1) { - PsiExpression childEl = argsExpressions[0] - if (!(childEl instanceof PsiLiteralExpression)) { - log.info "not psi literal : ${childEl}" - return null - } - String value2 = getStringFromPsiLiteral(childEl); - if (value2 == null) { - log.debug "not a string" - return null; - } - return new File(value2) -// FileCompletionBean fileCompletionBean = new FileCompletionBean() -// fileCompletionBean.value = value2 - - } - if (argsExpressions.length != 2) { - log.debug "too many args" - return null; - } - PsiExpression childEl = argsExpressions[1] - if (!(childEl instanceof PsiLiteralExpression)) { - log.info "not psi literal : ${childEl}" - return null - } - File parentFile = findFileFromVarGeneric(argsExpressions[0]) - if (parentFile == null) { - return null - } - if (!addSuffix) { - return parentFile - } - String value2 = getStringFromPsiLiteral(childEl); - if (value2 == null) { - log.debug "not a string" - return null; - } - return new File(parentFile, value2) - } - - private static File javaFileViaNewExpression2(PsiNewExpression grExpression) { - PsiType type = grExpression.type; - if (!(type instanceof PsiClassType)) { - log.debug "not a type" - return null; - } - PsiClass psiClass = type.resolve(); - if (psiClass == null || psiClass.name == null || !(psiClass.name.contains('File'))) { - log.debug "not a file" - return null; - } - if (grExpression.argumentList.expressions.length == 1) { - PsiExpression element = grExpression.argumentList.expressions[0] - String value2 = getStringFromPsiLiteral(element); - if (value2 == null) { - log.debug "not a string" - return null; - } - return new File(value2); - } - if (grExpression.argumentList.expressions.length != 2) { - log.debug "too many args" - return null; - } - log.debug "not implemented" - return null - } - - /** - * Resolve groovy construction new File('path') and new File(parent,'path') - * @param grExpression - * @param addSuffix indecatios if need resolve child path for 2 args constructor - * @return - */ - private static File fileViaGroovyNewExpression3(GrNewExpression grExpression, boolean addSuffix) { - PsiType type = grExpression.type; - if (!(type instanceof GrClassReferenceType)) { - log.debug "not a type" - return null; - } - PsiClass resolve = type.resolve() - - if (resolve == null || !(resolve.name.contains('File'))) { - log.debug "not a file" - return null; - } - if (grExpression.argumentList.allArguments.length == 1) { - GroovyPsiElement element = grExpression.argumentList.allArguments[0] - String value2 = getStringFromPsiLiteral(element); - if (value2 == null) { - log.debug "not a string" - return null; - } - return new File(value2); - } - if (grExpression.argumentList.allArguments.length != 2) { - log.debug "too many args" - return null; - } - GroovyPsiElement arg = grExpression.argumentList.allArguments[0] - File fileParent = findFileFromVarGeneric(arg); - if (fileParent == null) { - return null - } - if (!addSuffix) { - return fileParent - } - String suffixFile = getStringFromPsiLiteral(grExpression.argumentList.allArguments[1]); - if (suffixFile == null) { - return null - } - return new File(fileParent, suffixFile) - } - - /** - * Calculate path for field. - * Example : File parent = new File('/opt'); - * use parent somewhere. This method calc path for parent field - */ - private static File javaFindFileFromField(final PsiField psiField) { - PsiField psiField2 = psiField - if (psiField2.navigationElement != null && psiField2.navigationElement instanceof PsiField) { - log.debug "use navigation el" - psiField2 = psiField2.navigationElement as PsiField - } - PsiExpression initializer = psiField2.initializer - if (initializer instanceof PsiNewExpression) { - File fileResolved = javaFileViaNewExpression2(initializer); - return fileResolved; - } - if (initializer == null) { - if (!(psiField2 instanceof PsiCompiledElement)) { - log.debug "not a psi compile" - return null; - } - PsiElement mirror = psiField2.getMirror(); - if (!(mirror instanceof PsiField)) { - log.debug "not a field" - return null; - } - psiField2 = mirror; - } else { - log.info "not imeplementted initializer : ${initializer.class.name} ${initializer}" - return null - } - if (psiField2 instanceof GrField) { - return findFileFromVarGeneric(psiField2.getInitializerGroovy()) - } - if (psiField2 != psiField) { - return javaFindFileFromField(psiField2) - } - log.debug "not gr field ${psiField2?.class.name} ${psiField2}" - - return null - } - - @Override - public boolean accepts(@Nullable Object o, ProcessingContext context) { - return accepts(o); - } - - @Override - public ElementPatternCondition getCondition() { - log.debug(1) - return new ElementPatternCondition(null); - } - - - private - static File fileViaFileChildMethod(GrMethodCallExpression grExpression, boolean addSuffix) { - - GrExpression invokedExpression = grExpression.invokedExpression - if (!(invokedExpression instanceof GrReferenceExpressionImpl)) { - log.info "not GrReferenceExpressionImpl : ${invokedExpression.class.name} ${invokedExpression}" - return null - } - String methodName = invokedExpression.getReferenceName() - if (methodName != 'child') { - log.debug "method name is not child : ${methodName}" - return null - } - PsiElement[] children = grExpression.children - if (children.length != 2) { - log.debug "too low childerns" - return null - } - File parentFile = findFileFromVarGeneric(invokedExpression.getFirstChild()) - if (parentFile == null) { -// log.debug "parent file not found" - return null - } - if (!addSuffix) { - return parentFile - } - String suffixFile = getStringFromPsiLiteral(grExpression.argumentList.allArguments[0]); - if (suffixFile == null) { - return null - } - return new File(parentFile, suffixFile) - } - - private void notUsed() { - File f = "c:/1/" as File - - } - -} +package idea.plugins.thirdparty.filecompletion.jrr.a.file + +import com.intellij.lang.jvm.JvmMember +import com.intellij.lang.jvm.JvmTypeDeclaration +import com.intellij.lang.jvm.types.JvmReferenceType +import com.intellij.patterns.ElementPattern +import com.intellij.patterns.ElementPatternCondition +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiClassType +import com.intellij.psi.PsiCompiledElement +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiExpression +import com.intellij.psi.PsiField +import com.intellij.psi.PsiIdentifier +import com.intellij.psi.PsiJavaToken +import com.intellij.psi.PsiLiteral +import com.intellij.psi.PsiLiteralExpression +import com.intellij.psi.PsiNewExpression +import com.intellij.psi.PsiReferenceExpression +import com.intellij.psi.PsiType +import com.intellij.psi.PsiVariable +import com.intellij.psi.impl.source.tree.LeafPsiElement +import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl +import com.intellij.util.ProcessingContext +import groovy.transform.CompileStatic +import idea.plugins.thirdparty.filecompletion.jrr.IdeaMagic +import idea.plugins.thirdparty.filecompletion.jrr.a.remoterun.JrrIdeaBean +import idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.FieldResolvedDirectly +import idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.FieldResolvedDirectlyMoreComplex +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.CustomObjectHandler +import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.nonjdk.TwoResult +import net.sf.jremoterun.utilities.nonjdk.git.GitSpec +import net.sf.jremoterun.utilities.nonjdk.git.SvnSpec +import org.apache.log4j.LogManager +import org.apache.log4j.Logger +import org.jetbrains.annotations.Nullable +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement +import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSafeCastExpression +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod +import org.jetbrains.plugins.groovy.lang.psi.impl.GrClassReferenceType +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrNewExpressionImpl +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl + +@CompileStatic +public class MyAcceptFileProviderImpl implements ElementPattern { + + // this is log file + public static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); + + + @Override + boolean accepts(@Nullable Object o) { + log.debug " accept : ${o?.class.name}" + if (o instanceof LeafPsiElement) { + JrrIdeaBean.bean.psiElement2 = (PsiElement) o; + boolean accept = isOkJavaAndGroovyPsiElement(o) != null; + return accept; + } + return false; + // + } + + static File isOkJavaPsiElement3(PsiJavaToken leafPsiElement) { + PsiElement parent = leafPsiElement.parent.parent.parent + if (!(parent instanceof PsiNewExpression)) { + log.debug("not new expression") + return null; + } +// PsiNewExpression newExpression = (PsiNewExpression) parent + log.debug "${parent}" + return javaFileViaNewExpression7(parent, true); + } + + static FileCompletionBean isOkJavaPsiElement(PsiJavaToken leafPsiElement, boolean addSuffix) { + PsiElement parent = leafPsiElement.parent.parent.parent + if (!(parent instanceof PsiNewExpression)) { + log.debug("not new expression") + return null; + } +// PsiNewExpression newExpression = (PsiNewExpression) parent + log.debug "${parent}" + PsiNewExpression pn = parent + TwoResult res3 = javaFileViaNewExpression3(pn, addSuffix); + if (res3 == null) { + return null + } + PsiExpression[] argsExpressions = pn.argumentList.expressions + PsiExpression element = argsExpressions.toList().last() + String value2 = getStringFromPsiLiteral(element); + if (value2 == null) { + log.debug "not a string" + return null; + } + FileCompletionBean fileCompletionBean = new FileCompletionBean() + fileCompletionBean.wholeFileDeclaration = parent + fileCompletionBean.value = value2 + fileCompletionBean.parentFilePath = res3.second + return fileCompletionBean + + } + + static FileCompletionBean isOkJavaAndGroovyPsiElement(LeafPsiElement leafPsiElement) { + if (leafPsiElement instanceof PsiJavaTokenImpl) { + return isOkJavaPsiElement(leafPsiElement, false) + } + PsiElement parent = leafPsiElement.getParent(); + if (!(parent instanceof PsiLiteral)) { + return null; + } + Object value = parent.getValue(); + if (!(value instanceof String)) { + return null; + } + FileCompletionBean completionBean = new FileCompletionBean(); + completionBean.value = getStringFromPsiLiteral(parent) + if (completionBean.value == null) { + return null; + } + // log.debug "value = ${completionBean.value}" + completionBean.literalElemtnt = parent; + PsiElement parent1 = parent.parent; + PsiElement parent2 = parent1.parent + if (parent1 instanceof GrArgumentList) { + if (parent2 instanceof GrNewExpression) { + TwoResult res = fileViaGrNewExpression(parent2) + if (res != null && res.first) { + completionBean.wholeFileDeclaration = parent2 + completionBean.parentFilePath = res.second + return completionBean + } + return null + } + } + if (parent1 instanceof GrSafeCastExpression) { + File file = resolveFileFromSafeCast(parent1) + if (file != null) { + completionBean.wholeFileDeclaration = parent1 + return completionBean + } + + } + + if (parent2 instanceof GrMethodCallExpression) { + File file = fileViaFileChildMethod(parent2, false) + if (file != null) { + completionBean.wholeFileDeclaration = parent1 + completionBean.parentFilePath = file + return completionBean + } + + } + + return null; + } + + /** + * Calculate path for var. + * Example : File parent = new File('/opt'); + * use parent somewhere. This method calc path for parent var + */ + static File findFileFromVarGeneric(final PsiElement varRef) { + if (varRef == null) { + log.warn("ref is null", new Exception()) + return null + } + if (varRef instanceof GrReferenceExpression) { + // may be use resolve ? + // varRef.resolve() + File result = FieldResolvedDirectlyMoreComplex.fieldResolvedDirectlyMoreComplex.tryResolveFileViaGrRef(varRef) + if(result!=null){ + return result; + } + GroovyResolveResult[] variants = varRef.getSameNameVariants() + if (variants == null) { + log.debug "variants is null" + return null + } + if (variants.length != 1) { + log.debug "args not 1" + return null + } + PsiElement element = variants[0].element + if (element == null) { + log.debug "failed resolve el var for ${varRef}" + return null + } + if (element == varRef) { + log.info "cycle ${varRef}" + return null + } + return findFileFromVarGeneric(element) + } + if (varRef instanceof PsiReferenceExpression) { + File result = FieldResolvedDirectlyMoreComplex.fieldResolvedDirectlyMoreComplex.tryResolveFileViaJavaRef(varRef) + if(result!=null){ + return result; + } + PsiElement resolve = varRef.resolve() + if (resolve == null) { + log.info "failed resolve ${varRef}" + return null + } + if (resolve == varRef) { + log.info "cycle : ${varRef}" + return null + } + return findFileFromVarGeneric(resolve) + } + if (varRef instanceof GrField) { + File result = FieldResolvedDirectlyMoreComplex.fieldResolvedDirectlyMoreComplex.tryResolveFile(varRef) + if(result!=null){ + return result + } + GrExpression gr1 = varRef.getInitializerGroovy() + if (gr1 == null) { + log.debug "null init for ${varRef}" + return null + } + return findFileFromVarGeneric(gr1) + } + if (varRef instanceof PsiField) { + PsiClass containingClass = varRef.getContainingClass() + String name = varRef.getName() + String cassName = containingClass.getQualifiedName() + boolean canResolve = FieldResolvedDirectly.fieldResolvedDirectly.canResolve(cassName,name) + if(canResolve){ + return FieldResolvedDirectly.fieldResolvedDirectly.resolveValue(cassName,name) + } + return javaFindFileFromField(varRef) + } + if (varRef instanceof GrVariable) { + GrExpression gr1 = varRef.getInitializerGroovy() + if (gr1 == null) { + log.debug "null init for ${varRef}" + return null + } + return findFileFromVarGeneric(gr1) + } + if (varRef instanceof GrAccessorMethod) { + PsiElement navigationElement = varRef.getNavigationElement() + if (navigationElement == null) { + log.info "navigation el is null" + } else { + if (navigationElement != varRef) { + return findFileFromVarGeneric(navigationElement) + } + } + } + + // new begin + if (varRef instanceof GrSafeCastExpression) { + return resolveFileFromSafeCast(varRef) + } + if (varRef instanceof GrNewExpression) { + return fileViaGroovyNewExpression3(varRef, true); + } + if (varRef instanceof GrMethodCallExpression) { + return fileViaFileChildMethod(varRef, true); + } + if (varRef instanceof PsiNewExpression) { + javaFileViaNewExpression7(varRef, true) + } + // new end + + log.debug "not a GrVar : ${varRef.class} ${varRef}" + return null; + } + + static String getStringFromPsiLiteral(PsiElement psiElement) { + if (!(psiElement instanceof PsiLiteral)) { + return null; + } + PsiLiteral literalElemtnt = (PsiLiteral) psiElement; + Object value = literalElemtnt.getValue(); + if (!(value instanceof String)) { + return null; + } + return value.replace(IdeaMagic.addedConstant, ''); + } + + + private static File resolveFileFromSafeCast(GrSafeCastExpression castExpression) { + String text = castExpression.type.presentableText + if (text != null && text.contains('File')) { + log.debug("accpted") + String literal = getStringFromPsiLiteral(castExpression.operand) + if (literal == null) { + log.debug "not a tsring" + return null; + } + return new File(literal); + } + return null + } + + /** + * Internal method + */ + private + static TwoResult fileViaGrNewExpression(GrNewExpression grExpression) { + PsiType type = grExpression.getType(); + if (!(type instanceof GrClassReferenceType)) { + return null + } + PsiClass resolve = type.resolve() + + if (resolve == null || !(resolve.getName().contains('File'))) { + log.debug("accpted") + return null + } + if (grExpression.argumentList.allArguments.length == 1) { + String literal = getStringFromPsiLiteral(grExpression.argumentList.allArguments[0]); + if (literal == null) { + log.debug "not a string" + return null + } + return new TwoResult(true, null); + } + if (grExpression.argumentList.allArguments.length == 2) { + File parentFilePath = fileViaGroovyNewExpression3(grExpression, false) + if (parentFilePath == null) { + return null + } + return new TwoResult(true, parentFilePath); +// return completionBean.parentFilePath != null; + } + return null + } + + /** + * Resolve java construction new File('path') + * java construction not supported : new File(parent,'child') + * but for groovy supported + * @param grExpression + * @param addSuffix + * @return + */ + private + static TwoResult javaFileViaNewExpression3(PsiNewExpression grExpression, boolean addSuffix) { + PsiType type = grExpression.type; + if (!(type instanceof PsiClassType)) { + log.debug "not a type" + return null; + } + PsiClass psiClass = type.resolve(); + if (psiClass == null || psiClass.name == null || !(psiClass.name.contains('File'))) { + log.debug "not a file" + return null; + } + PsiExpression[] argsExpressions = grExpression.argumentList.expressions + if (argsExpressions.length == 1) { + return new TwoResult(true, null); + } + if (argsExpressions.length == 2) { + log.debug "too many args" + File fff = javaFileViaNewExpression7(grExpression, addSuffix) + if (fff == null) { + return null; + } + return new TwoResult(true, fff); + + + } + log.debug "not implemented" + return null + } + + private static File javaFileViaNewExpression7(PsiNewExpression grExpression, boolean addSuffix) { + PsiType type = grExpression.type; + if (!(type instanceof PsiClassType)) { + log.debug "not a type" + return null; + } + PsiClass psiClass = type.resolve(); + if (psiClass == null || psiClass.name == null || !(psiClass.name.contains('File'))) { + log.debug "not a file" + return null; + } + PsiExpression[] argsExpressions = grExpression.argumentList.expressions + if (argsExpressions.length == 1) { + PsiExpression childEl = argsExpressions[0] + if (!(childEl instanceof PsiLiteralExpression)) { + log.info "not psi literal : ${childEl}" + return null + } + String value2 = getStringFromPsiLiteral(childEl); + if (value2 == null) { + log.debug "not a string" + return null; + } + return new File(value2) + } + if (argsExpressions.length != 2) { + log.debug "too many args" + return null; + } + PsiExpression childEl = argsExpressions[1] + if (!(childEl instanceof PsiLiteralExpression)) { + log.info "not psi literal : ${childEl}" + return null + } + File parentFile = findFileFromVarGeneric(argsExpressions[0]) + if (parentFile == null) { + return null + } + if (!addSuffix) { + return parentFile + } + String value2 = getStringFromPsiLiteral(childEl); + if (value2 == null) { + log.debug "not a string" + return null; + } + return new File(parentFile, value2) + } + + private static File javaFileViaNewExpression2(PsiNewExpression grExpression) { + PsiType type = grExpression.type; + if (!(type instanceof PsiClassType)) { + log.debug "not a type" + return null; + } + PsiClass psiClass = type.resolve(); + if (psiClass == null || psiClass.name == null || !(psiClass.name.contains('File'))) { + log.debug "not a file" + return null; + } + if (grExpression.argumentList.expressions.length == 1) { + PsiExpression element = grExpression.argumentList.expressions[0] + String value2 = getStringFromPsiLiteral(element); + if (value2 == null) { + log.debug "not a string" + return null; + } + return new File(value2); + } + if (grExpression.argumentList.expressions.length != 2) { + log.debug "too many args" + return null; + } + log.debug "not implemented" + return null + } + + /** + * Resolve groovy construction new File('path') and new File(parent,'path') + * @param grExpression + * @param addSuffix indecatios if need resolve child path for 2 args constructor + * @return + */ + private static File fileViaGroovyNewExpression3(GrNewExpression grExpression, boolean addSuffix) { + PsiType type = grExpression.type; + if (!(type instanceof GrClassReferenceType)) { + log.debug "not a type" + return null; + } + PsiClass resolve = type.resolve() + + if (resolve == null || !(resolve.name.contains('File'))) { + log.debug "not a file" + return null; + } + if (grExpression.argumentList.allArguments.length == 1) { + GroovyPsiElement element = grExpression.argumentList.allArguments[0] + String value2 = getStringFromPsiLiteral(element); + if (value2 == null) { + log.debug "not a string" + return null; + } + return new File(value2); + } + if (grExpression.argumentList.allArguments.length != 2) { + log.debug "too many args" + return null; + } + GroovyPsiElement arg = grExpression.argumentList.allArguments[0] + File fileParent = findFileFromVarGeneric(arg); + if (fileParent == null) { + return null + } + if (!addSuffix) { + return fileParent + } + String suffixFile = getStringFromPsiLiteral(grExpression.argumentList.allArguments[1]); + if (suffixFile == null) { + return null + } + return new File(fileParent, suffixFile) + } + + /** + * Calculate path for field. + * Example : File parent = new File('/opt'); + * use parent somewhere. This method calc path for parent field + */ + private static File javaFindFileFromField(final PsiField psiField) { + PsiField psiField2 = psiField + if (psiField2.navigationElement != null && psiField2.navigationElement instanceof PsiField) { + log.debug "use navigation el" + psiField2 = psiField2.navigationElement as PsiField + } + PsiExpression initializer = psiField2.initializer + if (initializer instanceof PsiNewExpression) { + File fileResolved = javaFileViaNewExpression2(initializer); + return fileResolved; + } + if (initializer == null) { + if (!(psiField2 instanceof PsiCompiledElement)) { + log.debug "not a psi compile" + return null; + } + PsiElement mirror = psiField2.getMirror(); + if (!(mirror instanceof PsiField)) { + log.debug "not a field" + return null; + } + psiField2 = mirror; + } else { + log.info "not imeplementted initializer : ${initializer.class.name} ${initializer}" + return null + } + if (psiField2 instanceof GrField) { + return findFileFromVarGeneric(psiField2.getInitializerGroovy()) + } + if (psiField2 != psiField) { + return javaFindFileFromField(psiField2) + } + log.debug "not gr field ${psiField2?.class.name} ${psiField2}" + + return null + } + + @Override + public boolean accepts(@Nullable Object o, ProcessingContext context) { + return accepts(o); + } + + @Override + public ElementPatternCondition getCondition() { + log.debug(1) + return new ElementPatternCondition(null); + } + + + private static File resolveToFileMethod(GrMethodCallExpression grExpression) { + // invokedExpression = GitReferences.purejavacommTraffSrc.resolveToFile() + GrReferenceExpressionImpl invokedExpression = grExpression.invokedExpression as GrReferenceExpressionImpl + String methodName = invokedExpression.getReferenceName() + assert methodName == SpecialMethodName.resolveToFile.name() + // firstChild = GitReferences.purejavacommTraffSrc; + PsiElement firstChild = invokedExpression.getFirstChild() + if (!(firstChild instanceof GrReferenceExpression)) { + log.info "not GrRef" + return null + } + // child2 = GitReferences + PsiElement child2 = firstChild.getFirstChild() + if (!(child2 instanceof GrReferenceExpression)) { + log.info "firstChild no psi : ${child2}" + return null + } + PsiElement psiField = firstChild.resolve() + if (!(psiField instanceof PsiField)) { + log.info("not psi field : ${psiField}") + return null + } + PsiField psiVar = psiField as PsiField + PsiClass containingClass = psiVar.getContainingClass() +// PsiType type1 = psiVar.getType() +// if (!(type1 instanceof PsiClass)) { +// log.info("not psi class : ${type1}") +// return null +// } +// PsiClass psiClass = type1 as PsiClass + String className1 = containingClass.getQualifiedName(); + PsiIdentifier pi = psiVar.getNameIdentifier(); + String fieldName = pi.getText(); + boolean canResolveB=FieldResolvedDirectly.fieldResolvedDirectly.canResolveEnum(className1); + if(!canResolveB){ + log.info "not in scope : ${className1}" + return null + } + + Object fieldValue = FieldResolvedDirectly.fieldResolvedDirectly.resolveValue2(className1, fieldName); +// if (!(fieldValue instanceof GitSpec)) { +// log.info "not git spec : ${fieldValue}" +// return null +// } + CustomObjectHandler handler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler + if(handler==null){ + throw new IllegalStateException("customObjectHandler was not set") + } + File f = handler.resolveToFileIfDownloaded(fieldValue) + log.info "resolved : ${f}" + return f + } + + private static File childLazyMethodResolveParent(PsiElement firstChild ) { + if (firstChild instanceof GrNewExpressionImpl) { + PsiType type = firstChild.getType(); + if (!(type instanceof GrClassReferenceType)) { + return null + } + PsiClass resolve = type.resolve() + + if (resolve == null) { + log.info "not git spec 1 ${type}" + return null + } + boolean isSvnSpec= false; + if (!(resolve.getName().contains(GitSpec.getSimpleName()))) { + log.info("not git spec: ${resolve}") + if(resolve.getName().contains(SvnSpec.getSimpleName())){ + isSvnSpec = true + }else { + return null + } + } + GrArgumentList args = firstChild.getArgumentList() + GroovyPsiElement[] arguments = args.getAllArguments() + if (arguments == null || arguments.length != 1) { + log.info "bad args : ${arguments}" + return null + } + GroovyPsiElement firstArg = arguments[0] + if (firstArg instanceof GrLiteral) { + GrLiteral literal = (GrLiteral) firstArg; + String gitRefValue = literal.getValue() + CustomObjectHandler handler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler + if(handler==null){ + throw new IllegalStateException("customObjectHandler was not set") + } + Object gitSpec; + if(isSvnSpec){ + gitSpec = new SvnSpec(gitRefValue) + }else{ + gitSpec = new GitSpec(gitRefValue) + } + File f = handler.resolveToFileIfDownloaded(gitSpec) + if(f==null){ + log.info "failed resolved ${gitSpec}" + } + return f; + } + } + if (!(firstChild instanceof GrReferenceExpression)) { + log.info "not GrRef ${firstChild.getClass()} ${firstChild}" + return null + } + // child2 = GitReferences + PsiElement child2 = firstChild.getFirstChild() + if (!(child2 instanceof GrReferenceExpression)) { + log.info "firstChild no psi : ${child2}" + return null + } + PsiElement psiField = firstChild.resolve() + if (!(psiField instanceof PsiField)) { + log.info("not psi field : ${psiField}") + return null + } + PsiField psiVar = psiField as PsiField + PsiClass containingClass = psiVar.getContainingClass() +// PsiType type1 = psiVar.getType() +// if (!(type1 instanceof PsiClass)) { +// log.info("not psi class : ${type1}") +// return null +// } +// PsiClass psiClass = type1 as PsiClass + String className1 = containingClass.getQualifiedName(); + PsiIdentifier pi = psiVar.getNameIdentifier(); + String fieldName = pi.getText() + boolean canResolveB = FieldResolvedDirectly.fieldResolvedDirectly.canResolveEnum(className1) + if (!canResolveB) { + log.info "not in scope : ${className1}" + return null + } + + Object fieldValue = FieldResolvedDirectly.fieldResolvedDirectly.resolveValue2(className1, fieldName); +// if (!(fieldValue instanceof GitSpec)) { +// log.info "not git spec : ${fieldValue}" +// return null +// } + CustomObjectHandler handler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler + if (handler == null) { + throw new IllegalStateException("customObjectHandler was not set") + } + File f = handler.resolveToFileIfDownloaded(fieldValue) + log.info "resolved : ${f}" + return f; + } + + private static File childLazyMethod(GrMethodCallExpression grExpression, boolean addSuffix) { + // invokedExpression = GitReferences.purejavacommTraffSrc.resolveToFile() + GrReferenceExpressionImpl invokedExpression = grExpression.invokedExpression as GrReferenceExpressionImpl + String methodName = invokedExpression.getReferenceName() + assert methodName == SpecialMethodName.childL.name() + // firstChild = GitReferences.purejavacommTraffSrc; + PsiElement firstChild = invokedExpression.getFirstChild() + File f = childLazyMethodResolveParent(firstChild); + if(f ==null){ + return null + } + if(!addSuffix) { + return f + } + String suffixFile = getStringFromPsiLiteral(grExpression.argumentList.allArguments[0]); + if (suffixFile == null) { + return null + } + return new File(f, suffixFile) + + } + + private + static File fileViaFileChildMethod(GrMethodCallExpression grExpression, boolean addSuffix) { + + GrExpression invokedExpression = grExpression.invokedExpression + if (!(invokedExpression instanceof GrReferenceExpressionImpl)) { + log.info "not GrReferenceExpressionImpl : ${invokedExpression.class.name} ${invokedExpression}" + return null + } + String methodName = invokedExpression.getReferenceName() + if(methodName == SpecialMethodName.resolveToFile.name()){ + return resolveToFileMethod(grExpression) + } + if (methodName == SpecialMethodName.childL.name()) { + return childLazyMethod(grExpression,addSuffix) + } + if (methodName != SpecialMethodName.child.name()) { + log.debug "method name is not child : ${methodName}" + return null + } + PsiElement[] children = grExpression.children + if (children.length != 2) { + log.debug "too low childerns" + return null + } + File parentFile = findFileFromVarGeneric(invokedExpression.getFirstChild()) + if (parentFile == null) { +// log.debug "parent file not found" + return null + } + if (!addSuffix) { + return parentFile + } + String suffixFile = getStringFromPsiLiteral(grExpression.argumentList.allArguments[0]); + if (suffixFile == null) { + return null + } + return new File(parentFile, suffixFile) + } + + private void notUsed() { + File f = "c:/1/" as File + + } + +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/SpecialMethodName.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/SpecialMethodName.groovy new file mode 100644 index 00000000..20f571af --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/SpecialMethodName.groovy @@ -0,0 +1,15 @@ +package idea.plugins.thirdparty.filecompletion.jrr.a.file + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +enum SpecialMethodName { + resolveToFile, + childL, + child, + ; + + +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleEnum.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleEnum.groovy new file mode 100644 index 00000000..2beb7630 --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleEnum.groovy @@ -0,0 +1,22 @@ +package idea.plugins.thirdparty.filecompletion.jrr.a.file.sample + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +enum SampleEnum { + a1('c:/Users/' as File), + a2('c:/windows/' as File), + ; + + public File f; + + SampleEnum(File f) { + this.f = f + } + + File getF2(){ + return f; + } +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleGroovy.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleGroovy.groovy index 072ffdd4..296c4872 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleGroovy.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleGroovy.groovy @@ -1,25 +1,37 @@ -package idea.plugins.thirdparty.filecompletion.jrr.a.file.sample - -import groovy.transform.CompileStatic -import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds - -import java.nio.charset.Charset; - -/** - * Created by nick on 04.03.2017. - */ -@CompileStatic -public class SampleGroovy { - - public static File file1 = new File("c:/1/"); - - private void testNoyUsed(){ - new File("c:/windows/System32/drivers/"); - Charset.forName("273"); - "aaa".toString() - file1.toString(); - "C:\\progi\\idea\\2017.2ce\\lib\\annotations.jar" as File - LatestMavenIds.sshd.toString() - file1.child("gcc2/regeva/jremoterun-1.0.zip"); - } -} +package idea.plugins.thirdparty.filecompletion.jrr.a.file.sample + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JeditermBinRefs2 +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.SshdMavenIds +import net.sf.jremoterun.utilities.nonjdk.git.GitSpec + +import java.nio.charset.Charset; + + +@CompileStatic +public class SampleGroovy { + + public static File file1 = new File("c:/1/"); + + private void testNoyUsed(){ + GitSomeRefs.jtermGitSpec.childL('terminal/build.gradle'); + new GitSpec('https://github.com/JetBrains/jediterm').childL('terminal/build.gradle'); + GitSomeRefs.jtermGitSpec.childL('terminal/src/com/jediterm/terminal/DataStreamIteratingEmulator.java'); + GitSomeRefs.jtermGitSpec.resolveToFile().child('lib/javac2.jar'); + JeditermBinRefs2.terminal.childL('com/jediterm/terminal/ArrayTerminalDataStream.java') + + new File("c:/windows/System32/drivers/"); + Charset.forName("273"); + System.getProperty('user.home') + "aaa".toString() + file1.toString(); + "C:\\progi\\idea\\2017.2ce\\lib\\annotations.jar" as File + SshdMavenIds.core.toString() + file1.child("gcc2/regeva/jremoterun-1.0.zip"); + SampleJava.f.child('a.txt') + SampleEnum.a2.f.child('System32') + } +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleJava.java b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleJava.java index e657c007..1ab8f816 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleJava.java +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/file/sample/SampleJava.java @@ -1,20 +1,19 @@ -package idea.plugins.thirdparty.filecompletion.jrr.a.file.sample; - -import java.io.File; -import java.nio.charset.Charset; - -/** - * Created by nick on 04.03.2017. - */ -public class SampleJava { - - public static File f = new File("c:/a/"); - - private void testNoyUsed(){ - new File("c:/windows/System32/drivers/"); - Charset.forName("273"); - f.toString(); - new File(SampleGroovy.file1, ".gitignore"); - new File(f, ".gitignore"); - } -} +package idea.plugins.thirdparty.filecompletion.jrr.a.file.sample; + +import java.io.File; +import java.nio.charset.Charset; + + +public class SampleJava { + + public static File f = new File("c:/a/"); + + private void testNoyUsed(){ + new File("c:/windows/System32/drivers/"); + Charset.forName("273"); + f.toString(); + new File(SampleGroovy.file1, ".gitignore"); + new File(f, ".gitignore"); + new File(SampleEnum.a1.f, ".gitignore"); + } +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/javadocredirect/SimpleDateFormatHelper.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/javadocredirect/SimpleDateFormatHelper.groovy index f1dd1c6f..51cdb6ba 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/javadocredirect/SimpleDateFormatHelper.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/javadocredirect/SimpleDateFormatHelper.groovy @@ -109,8 +109,8 @@ public class SimpleDateFormatHelper { private void test() { Date date = null new SimpleDateFormat('yyyy-MM') - new Date().format('yyyy-MM') - date.format('yyyy-MM') + //new Date().format('yyyy-MM') + //date.format('yyyy-MM') } @@ -118,10 +118,10 @@ public class SimpleDateFormatHelper { Date date = null Calendar calendar = null new SimpleDateFormat('yyyy-MM') - calendar.format('yyyy-MM') - new Date().format('yyyy-MM') - new Date().format('yyyy-MM', TimeZone.getTimeZone('Etc/GMT+3')) - date.format('yyyy-MM') + //calendar.format('yyyy-MM') + //new Date().format('yyyy-MM') + //new Date().format('yyyy-MM', TimeZone.getTimeZone('Etc/GMT+3')) + //date.format('yyyy-MM') Pattern p = ~"dsfsdfsd" } diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/javassist/JavassistCompletionProviderImpl.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/javassist/JavassistCompletionProviderImpl.groovy index 296025bd..20b8f6b3 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/javassist/JavassistCompletionProviderImpl.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/javassist/JavassistCompletionProviderImpl.groovy @@ -11,17 +11,17 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.util.ProcessingContext import groovy.transform.CompileStatic import idea.plugins.thirdparty.filecompletion.jrr.IdeaMagic +import idea.plugins.thirdparty.filecompletion.jrr.a.actions.CompletionProviderCommon import idea.plugins.thirdparty.filecompletion.jrr.a.file.MyAcceptFileProviderImpl import idea.plugins.thirdparty.filecompletion.jrr.a.jrrlib.ReflectionElement import net.sf.jremoterun.utilities.JrrClassUtils import org.apache.log4j.LogManager import org.apache.log4j.Logger -import org.jetbrains.annotations.NotNull import javax.swing.* @CompileStatic -public class JavassistCompletionProviderImpl extends CompletionProvider { +public class JavassistCompletionProviderImpl extends CompletionProviderCommon { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); @@ -33,7 +33,7 @@ public class JavassistCompletionProviderImpl extends CompletionProvider { +public class JrrCompletionProviderImpl extends CompletionProviderCommon { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); @Override protected void addCompletions( - @NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet result) { + CompletionParameters parameters, ProcessingContext context, CompletionResultSet result) { PsiElement psiElement = parameters.position; if (!(psiElement instanceof LeafPsiElement)) { return; diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/maven/MavenCompletionProviderImpl.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/maven/MavenCompletionProviderImpl.groovy index 9cc9ae19..971264c9 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/maven/MavenCompletionProviderImpl.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/maven/MavenCompletionProviderImpl.groovy @@ -12,6 +12,7 @@ import com.intellij.util.ProcessingContext import groovy.io.FileType import groovy.transform.CompileStatic import idea.plugins.thirdparty.filecompletion.jrr.IdeaMagic +import idea.plugins.thirdparty.filecompletion.jrr.a.actions.CompletionProviderCommon import idea.plugins.thirdparty.filecompletion.jrr.a.file.MyAcceptFileProviderImpl import idea.plugins.thirdparty.filecompletion.share.Ideasettings.IdeaJavaRunner2Settings import idea.plugins.thirdparty.filecompletion.share.OSIntegrationIdea @@ -23,12 +24,11 @@ import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.MavenId import org.apache.log4j.LogManager import org.apache.log4j.Logger -import org.jetbrains.annotations.NotNull import javax.swing.Icon @CompileStatic -public class MavenCompletionProviderImpl extends CompletionProvider { +public class MavenCompletionProviderImpl extends CompletionProviderCommon { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); @@ -217,7 +217,7 @@ public class MavenCompletionProviderImpl extends CompletionProvider { return false; } PsiClass psiClass = type.resolve(); - if (psiClass == null || !(psiClass.name.contains(MavenId.simpleName))) { + if (psiClass == null || !(psiClass.name.contains(MavenId.getSimpleName()))) { log.debug "not a maven id" return false; } @@ -99,7 +100,7 @@ public class MyAcceptMavenProviderImpl implements ElementPattern { log.info "enum type is null for ${e}" return false } - PsiType[] types = type.superTypes + PsiType[] types = type.getSuperTypes() if (types == null) { log.info("super type is null for ${type}") return false @@ -111,8 +112,12 @@ public class MyAcceptMavenProviderImpl implements ElementPattern { log.info("GrClassReferenceType not found for ${type}") return false } - GrClassReferenceType type1 = grClassReferenceTypes.find { it.name == MavenIdContains.getSimpleName() } + GrClassReferenceType type1 = grClassReferenceTypes.find { it.getName() == MavenIdContains.getSimpleName() } boolean found = type1 != null + if(!found){ + type1 = grClassReferenceTypes.find { it.getName() == MavenIdAndRepoContains.getSimpleName() } + found = type1 != null + } if (found) { log.info "type1 = ${type1}" diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/systemprop/SystemPropCompletionProviderImpl.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/systemprop/SystemPropCompletionProviderImpl.groovy index 2697d4ff..9cf2ff13 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/systemprop/SystemPropCompletionProviderImpl.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/a/systemprop/SystemPropCompletionProviderImpl.groovy @@ -11,18 +11,18 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.util.ProcessingContext import groovy.transform.CompileStatic import idea.plugins.thirdparty.filecompletion.jrr.IdeaMagic +import idea.plugins.thirdparty.filecompletion.jrr.a.actions.CompletionProviderCommon import idea.plugins.thirdparty.filecompletion.jrr.a.file.MyAcceptFileProviderImpl import idea.plugins.thirdparty.filecompletion.jrr.a.javassist.JavassistCompletionBean import idea.plugins.thirdparty.filecompletion.share.OSIntegrationIdea import net.sf.jremoterun.utilities.JrrClassUtils import org.apache.log4j.LogManager import org.apache.log4j.Logger -import org.jetbrains.annotations.NotNull import javax.swing.* @CompileStatic -public class SystemPropCompletionProviderImpl extends CompletionProvider { +public class SystemPropCompletionProviderImpl extends CompletionProviderCommon { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); @@ -31,7 +31,7 @@ public class SystemPropCompletionProviderImpl extends CompletionProvider { +public class TZCompletionProviderImpl extends CompletionProviderCommon { private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); @@ -42,7 +42,7 @@ public class TZCompletionProviderImpl extends CompletionProvider directClasses = new HashSet<>() + public HashSet directEnumClasses = new HashSet<>() + + public ClassLoader classLoader = getClass().getClassLoader() + + + + + void addDirectEnumClass(ClRef clazz){ + directEnumClasses.add(clazz.getName()) + } + + void addDirectEnumClass(Class clazz){ + directEnumClasses.add(clazz.getName()) + } + + boolean canResolveEnum(String className){ + log.info "checking can resolve enum : ${className} " + return directEnumClasses.contains(className); + } + + + void addDirectClass(ClRef clazz){ + directClasses.add(clazz.getName()) + } + + void addDirectClass(Class clazz){ + directClasses.add(clazz.getName()) + } + + + boolean canResolve(String className,String fieldName){ + log.info "checking can resolve : ${className} ${fieldName}" + return directClasses.contains(className) + } + + Class loadClass(String className){ + Class clazz = classLoader.loadClass(className) + return clazz + } + + + + + File resolveValue(String className,String fieldName){ + File file1 = resolveValue2(className,fieldName) as File + return file1 + + } + + + Object resolveValue2(String className,String fieldName){ + Thread thread = Thread.currentThread(); + ClassLoader loaderBefore = thread.getContextClassLoader() + thread.setContextClassLoader(classLoader) + try { + Class clazz = classLoader.loadClass(className) + return JrrClassUtils.getFieldValue(clazz, fieldName) + }finally{ + thread.setContextClassLoader(loaderBefore) + } + + } + + + + + +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/FieldResolvedDirectlyMoreComplex.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/FieldResolvedDirectlyMoreComplex.groovy new file mode 100644 index 00000000..357d36ed --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/FieldResolvedDirectlyMoreComplex.groovy @@ -0,0 +1,112 @@ +package idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator + +import com.intellij.lang.jvm.JvmTypeDeclaration +import com.intellij.lang.jvm.types.JvmReferenceType +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiClassType +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReferenceExpression +import com.intellij.psi.PsiType +import com.intellij.psi.impl.source.PsiImmediateClassType +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import org.codehaus.janino.ExpressionEvaluator +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression + +import java.util.logging.Logger + +@CompileStatic +class FieldResolvedDirectlyMoreComplex { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static FieldResolvedDirectlyMoreComplex fieldResolvedDirectlyMoreComplex = new FieldResolvedDirectlyMoreComplex(); + + File tryResolveFileViaJavaRef(PsiReferenceExpression grReferenceExpression) { + PsiElement[] children = grReferenceExpression.getChildren() + if (children == null) { + log.info "no childs" + return null + } + PsiElement firstChild = grReferenceExpression.getFirstChild() + if (firstChild == null) { + log.info "no first childs" + return null + } + if (!(firstChild instanceof PsiReferenceExpression)) { + log.info "firstChild no psi : ${firstChild}" + return null + } + PsiType type = firstChild.getType(); + return commonEnum(type, grReferenceExpression); + } + + File commonEnum(PsiType type, PsiElement psiElement) { + log.info("resolving : ${psiElement.getText()}") + if (!(type instanceof PsiClassType)) { + log.info("type not PsiClassType: ${type}") + return null; + } + PsiClass resolve = type.resolve(); + String qualifiedName = resolve.getQualifiedName(); + boolean canResolveB=FieldResolvedDirectly.fieldResolvedDirectly.canResolveEnum(qualifiedName) + if (!canResolveB) { + return null; + } + return resolveViaJavaExpression(qualifiedName,psiElement.getText()); + } + + File resolveViaJavaExpression(String className,String expression){ + ExpressionEvaluator ee = new ExpressionEvaluator(); + ee.setParameters(new String[0], new Class[0]); + + ee.setExpressionType(Object); + List impo = [] + impo.add(className) + ee.setParentClassLoader(FieldResolvedDirectly.fieldResolvedDirectly.classLoader) + ee.setDefaultImports(impo.toArray(new String[0])); + ee.cook(expression) + Object evaluate = ee.evaluate(new Object[0]) + if (evaluate instanceof File) { + File f = (File) evaluate; + log.info "resolved ${expression} to ${f}" + return f; + } + throw new Exception("got not file : ${expression} : ${evaluate}") + + } + + + File tryResolveFileViaGrRef(GrReferenceExpression grReferenceExpression) { + PsiElement[] children = grReferenceExpression.getChildren() + if (children == null) { + log.info("no childs") + return null + } + if (children.length != 1) { + log.info("childs not one : ${children.length}") + return null; + } + PsiElement psiElementChild = children[0] + if (!(psiElementChild instanceof GrReferenceExpression)) { + log.info("psiElementChild not grRef: ${psiElementChild}") + return null + } + PsiType type = psiElementChild.getType(); + return commonEnum(type, grReferenceExpression); + + } + + File tryResolveFile(GrField varRef) { + PsiClass containingClass = varRef.getContainingClass() + String name = varRef.getName() + String cassName = containingClass.getQualifiedName() + boolean canResolve = FieldResolvedDirectly.fieldResolvedDirectly.canResolve(cassName, name) + if (canResolve) { + return FieldResolvedDirectly.fieldResolvedDirectly.resolveValue(cassName, name) + } + return null + + } +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/FileChooserListener.java b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/FileChooserListener.java index 3f4944c3..97a2018e 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/FileChooserListener.java +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/FileChooserListener.java @@ -6,6 +6,7 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.TextFieldWithHistory; +import groovy.transform.CompileStatic; import net.sf.jremoterun.utilities.JrrClassUtils; import java.awt.event.ActionEvent; @@ -15,6 +16,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +@CompileStatic public class FileChooserListener implements ActionListener { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaAddFileWithSources.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaAddFileWithSources.groovy index 1978cb2a..f5290caa 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaAddFileWithSources.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaAddFileWithSources.groovy @@ -8,11 +8,17 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.JrrUtilities3 +import net.sf.jremoterun.utilities.NewValueListener import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.classpath.MavenDependenciesResolver import net.sf.jremoterun.utilities.mdep.ivy.IvyDepResolver2 import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.AddFileWithSources import net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers.ClassPathCalculatorSup2Groovy +import net.sf.jremoterun.utilities.nonjdk.ivy.IvyDepResolver3 +import net.sf.jremoterun.utilities.nonjdk.ivy.ManyReposDownloaderImpl +import net.sf.jremoterun.utilities.nonjdk.ivy.OnRepoCreatedListener +import java.util.logging.Level import java.util.logging.Logger @CompileStatic @@ -65,28 +71,37 @@ class IdeaAddFileWithSources extends AddFileWithSources { readyCallback.run() } } catch (Throwable e) { - log.info "${e}" - JrrUtilities.showException("Lib managed failed", e); + importFailed.newValue(e); } } } ProgressManager.getInstance().run(task); } + public static volatile NewValueListener importFailed = new NewValueListener() { + @Override + void newValue(Throwable throwable) { + log.log(Level.SEVERE,"Failed import",throwable) + JrrUtilities.showException("Failed import", throwable); + } + }; + IdeaIvyEvent prepare(File groovyClassPath, ProgressIndicator indicator) { IdeaClasspathLongTaskInfo longTaskInfo = new IdeaClasspathLongTaskInfo(indicator) - IvyDepResolver2 resolver = MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver as IvyDepResolver2 + ManyReposDownloaderImpl resolver = MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver as ManyReposDownloaderImpl + IdeaIvyEvent ideaIvyEvent = new IdeaIvyEvent(longTaskInfo); - resolver.ivy.eventManager.addIvyListener(ideaIvyEvent) + resolver.addIvyListener(ideaIvyEvent) try { import22(groovyClassPath) } finally { - resolver.ivy.eventManager.removeIvyListener(ideaIvyEvent) + resolver.removeIvyListener(ideaIvyEvent) } return ideaIvyEvent } + void import22(File groovyClassPath) { ClassPathCalculatorSup2Groovy cl = new ClassPathCalculatorSup2Groovy(); diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaAddFileWithSourcesFactory.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaAddFileWithSourcesFactory.groovy new file mode 100644 index 00000000..ba744ac7 --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaAddFileWithSourcesFactory.groovy @@ -0,0 +1,18 @@ +package idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class IdeaAddFileWithSourcesFactory { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public static IdeaAddFileWithSourcesFactory defaultFactory = new IdeaAddFileWithSourcesFactory(); + + IdeaAddFileWithSources createAdded(){ + return new IdeaAddFileWithSources(); + } + +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaLibManagerSwing.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaLibManagerSwing.groovy index b24b2a92..29091e58 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaLibManagerSwing.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaLibManagerSwing.groovy @@ -16,6 +16,9 @@ import net.sf.jremoterun.JrrUtils import net.sf.jremoterun.utilities.Java4VM import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.BaseDirSetting +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers.ClassPathCalculatorSup2Groovy import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import net.sf.jremoterun.utilities.nonjdk.idea.set2.SettingsRef @@ -60,7 +63,8 @@ class IdeaLibManagerSwing { DefaultMutableTreeNode globalLibNode = new DefaultMutableTreeNode("Global libraries") - FileStore listStore = new FileStore(new File("${System.getProperty('user.home')}/jrr/configs/idea_classpath_files_latest.groovy")) + public static ToFileRef2 ideaClassPathLatest = BaseDirSetting.baseDirSetting.childL("configs/idea_classpath_files_latest.groovy"); + FileStore listStore = new FileStore(ideaClassPathLatest.resolveToFile()); JTree tree = new JTree(rootTreeNode) JPanel topPanel = new JPanel4FlowLayout() @@ -204,7 +208,7 @@ class IdeaLibManagerSwing { } - saveSettings.setEnabled(SettingsRef.locationEdit.exists()) + saveSettings.setEnabled(SettingsRef.locationEdit.resolveToFile().exists()) // editSettings.setEnabled(!SettingsRef.locationEdit.exists()) panel.add(scrollPane, BorderLayout.CENTER) @@ -264,10 +268,10 @@ class IdeaLibManagerSwing { } private saveSettings() { - if (SettingsRef.locationEdit.exists()) { + if (SettingsRef.locationEdit.resolveToFile().exists()) { Runnable r3 = { OSIntegrationIdea.saveAllImpl2(); - if (SettingsRef.locationEdit.length() < 10) { + if (SettingsRef.locationEdit.resolveToFile().length() < 10) { log.info "file is empty ${SettingsRef.locationEdit}" JOptionPane.showMessageDialog(null, "file is empty ${SettingsRef.locationEdit}") } else { @@ -291,10 +295,10 @@ class IdeaLibManagerSwing { } private saveSettingsImpl() { - GroovyFileChecker.analize(SettingsRef.locationEdit.text) - SettingsRef.loadSettingsS(SettingsRef.locationEdit) - FileUtils.copyFile(SettingsRef.locationEdit, SettingsRef.location) - SettingsRef.locationEdit.text = '' + GroovyFileChecker.analize(SettingsRef.locationEdit.resolveToFile().text) + SettingsRef.loadSettingsS(SettingsRef.locationEdit.resolveToFile()) + FileUtilsJrr.copyFile(SettingsRef.locationEdit.resolveToFile(), SettingsRef.location.resolveToFile()) + SettingsRef.locationEdit.resolveToFile().text = '' log.info('settins loaded fine') SwingUtilities.invokeLater { try { @@ -312,21 +316,21 @@ class IdeaLibManagerSwing { private void editSetttingss() { boolean edit = editSetttingssImpl(); if (edit) { - OSIntegrationIdea.osIntegrationIdea.openFile(SettingsRef.locationEdit, '1.groovy') + OSIntegrationIdea.osIntegrationIdea.openFile(SettingsRef.locationEdit.resolveToFile(), '1.groovy') } } private boolean editSetttingssImpl() { SwingUtilities.invokeLater { saveSettings.setEnabled(true) } - if (SettingsRef.locationEdit.exists() && SettingsRef.locationEdit.length() > 100) { + if (SettingsRef.locationEdit.resolveToFile().exists() && SettingsRef.locationEdit.resolveToFile().length() > 100) { return true; } - if (SettingsRef.location.exists()) { - FileUtils.copyFile(SettingsRef.location, SettingsRef.locationEdit) + if (SettingsRef.location.resolveToFile().exists()) { + FileUtilsJrr.copyFile(SettingsRef.location.resolveToFile(), SettingsRef.locationEdit.resolveToFile()) return true } log.info "file not found : ${SettingsRef.location}" - File parentDir = SettingsRef.location.parentFile + File parentDir = SettingsRef.location.resolveToFile().getParentFile() if (!parentDir.exists()) { log.info "creating dirs : ${parentDir}" boolean mkdirs = parentDir.mkdirs() @@ -336,7 +340,7 @@ class IdeaLibManagerSwing { return false } } - SettingsRef.locationEdit.text = JavaBeanStore.save3(SettingsRef.config) + SettingsRef.locationEdit.resolveToFile().text = JavaBeanStore.save3(SettingsRef.config) log.info "file created" // SwingUtilities.invokeLater{editSettings.setEnabled(false)} return true; diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaRuntimeClassRefrences.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaRuntimeClassRefrences.groovy new file mode 100644 index 00000000..dcae2bb3 --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/IdeaRuntimeClassRefrences.groovy @@ -0,0 +1,42 @@ +package idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.groovystarter.JrrStarterVariables +import net.sf.jremoterun.utilities.nonjdk.BaseDirSetting +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkResourceDirs +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.ComplexGitRefs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustomRefsUrls +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JeditermBinRefs2 +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs2 +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterProjects +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.SvnRefs; + +import java.util.logging.Logger; + +@CompileStatic +class IdeaRuntimeClassRefrences { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static void addReferences(){ + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(GitSomeRefs) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(GitReferences) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(IfFrameworkSrcDirs) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(IfFrameworkResourceDirs) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(BaseDirSetting) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(ComplexGitRefs) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(CustomRefsUrls) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(JeditermBinRefs2) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(JrrStarterProjects) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(SvnRefs) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectClass(JrrStarterJarRefs) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectClass(JrrStarterVariables) + FieldResolvedDirectly.fieldResolvedDirectly.addDirectEnumClass(JrrStarterJarRefs2) + + } + +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibConfigurator8.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibConfigurator8.groovy index 3ed0201f..d34caaaf 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibConfigurator8.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibConfigurator8.groovy @@ -76,7 +76,7 @@ class LibConfigurator8 extends AddFileWithSources { TransactionGuard instance = TransactionGuard.getInstance(); log.info "instance.contextTransaction = ${instance.contextTransaction}" - boolean allowed = ApplicationManager.getApplication().writeAccessAllowed + boolean allowed = ApplicationManager.getApplication().isWriteAccessAllowed() log.info "wite access ${allowed}" if (instance.contextTransaction == null) { Runnable r2 = { @@ -89,7 +89,8 @@ class LibConfigurator8 extends AddFileWithSources { if (allowed) { r.run() } else { - ApplicationManager.getApplication().runWriteAction(r3) + ApplicationManager.getApplication().invokeLaterOnWriteThread(r3) + //ApplicationManager.getApplication().runWriteAction(r3) } } if (exc.object != null) { @@ -158,7 +159,7 @@ class LibConfigurator8 extends AddFileWithSources { @Override void addSourceFImpl(File source) { // VirtualFile file = fileToVirtual(source) - source = source.canonicalFile + source = source.getCanonicalFile() String escapedJarURL2 = createLibUrl(source); if (sources.contains(escapedJarURL2)) { log.info "already contains ${source}" diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibItem.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibItem.groovy index fe8e94d1..37dbe9db 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibItem.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibItem.groovy @@ -2,7 +2,6 @@ package idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator import com.intellij.openapi.roots.libraries.Library; import net.sf.jremoterun.utilities.JrrClassUtils -import org.jetbrains.annotations.NotNull; import java.util.logging.Logger; import groovy.transform.CompileStatic; @@ -25,7 +24,7 @@ class LibItem implements Comparable{ } @Override - int compareTo(@NotNull LibItem o) { + int compareTo( LibItem o) { return this.library.getName().compareTo(o.library.getName()) } diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibManager3.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibManager3.groovy index 7747c0ca..614affd0 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibManager3.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/LibManager3.groovy @@ -4,24 +4,29 @@ import com.intellij.openapi.Disposable import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.progress.Task +import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.Project import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.libraries.Library import groovy.transform.CompileStatic +import idea.plugins.thirdparty.filecompletion.jrr.IndexReadyListener import idea.plugins.thirdparty.filecompletion.share.OSIntegrationIdea import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.NewValueListener import net.sf.jremoterun.utilities.classpath.MavenCommonUtils import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.classpath.MavenDependenciesResolver import net.sf.jremoterun.utilities.classpath.MavenFileType2 import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.mdep.ivy.IvyDepResolver2 import net.sf.jremoterun.utilities.nonjdk.ideadep.LongTaskInfo +import net.sf.jremoterun.utilities.nonjdk.ivy.ManyReposDownloaderImpl import javax.swing.JOptionPane import javax.swing.SwingUtilities import java.awt.Component +import java.util.logging.Level import java.util.logging.Logger @CompileStatic @@ -64,10 +69,15 @@ public class LibManager3 { Task task = new Task.Backgroundable(project, "Add sources ...", true) { @Override public void run(ProgressIndicator indicator) { - Object result3 = addSources3(indicator, libItem) - if (valueListener4 != null) { - valueListener4.newValue(result3) + try { + Object result3 = addSources3(indicator, libItem) + if (valueListener4 != null) { + valueListener4.newValue(result3) + } + }catch(Throwable e){ + JrrUtilities.showException("Failed add source", e) } + } }; ProgressManager.getInstance().run(task); @@ -81,19 +91,22 @@ public class LibManager3 { List addSources3(ProgressIndicator progressIndicator, LibItem libItem) { IdeaClasspathLongTaskInfo longTaskInfo = new IdeaClasspathLongTaskInfo(progressIndicator) - IvyDepResolver2 resolver = MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver as IvyDepResolver2 + ManyReposDownloaderImpl resolver = MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver as ManyReposDownloaderImpl IdeaIvyEvent ideaIvyEvent = new IdeaIvyEvent(longTaskInfo); - resolver.ivy.eventManager.addIvyListener(ideaIvyEvent) + resolver.addIvyListener(ideaIvyEvent) try { List result = addSources2(longTaskInfo, libItem); - log.info("add dource done for ${libItem.library.getName()}") + log.info("add source done for ${libItem.library.getName()}") return result; } finally { - resolver.ivy.eventManager.removeIvyListener(ideaIvyEvent) + resolver.removeIvyListener(ideaIvyEvent) } } + public static boolean tryDownloadSourcesDefault = true + boolean tryDownloadSources = tryDownloadSourcesDefault + List addSources2(LongTaskInfo longTaskInfo, LibItem libItem) { // List noSourceInLocalSources = [] // log.info "found maven sources libs : ${alreadedAddedSources2}" @@ -112,12 +125,24 @@ public class LibManager3 { binWithMissingSources -= alreadedAddedSources2; log.info "found maven binaries without sources : ${binWithMissingSources}" + MavenCommonUtils mavenCommonUtilsSrc = new MavenCommonUtils(); + mavenCommonUtilsSrc.fileType = MavenFileType2.source.fileSuffix binWithMissingSources = binWithMissingSources.sort() - MavenCommonUtils mavenCommonUtils = new MavenCommonUtils(); - mavenCommonUtils.fileType = MavenFileType2.source.fileSuffix + if(tryDownloadSources) { + List allMissedSources = binWithMissingSources.findAll { + mavenCommonUtilsSrc.findMavenOrGradle(it) == null + } + MavenDependenciesResolver resolver = MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver + allMissedSources.each { + longTaskInfo.setCurrentTask("${it} downloading source ..") + resolver.resolveAndDownloadDeepDependencies(it,true,false) + } + + } + ls.noSourceInLocalSources.addAll(binWithMissingSources.findAll { - mavenCommonUtils.findMavenOrGradle(it) == null + mavenCommonUtilsSrc.findMavenOrGradle(it) == null }) ls.noSourceInLocalSources.sort() log.info "no sources ${ls.noSourceInLocalSources}" @@ -131,7 +156,11 @@ public class LibManager3 { msg = "No sources : ${ls.noSourceInLocalSources}, " } msg = "${msg}Can' add find more sources" - JOptionPane.showMessageDialog(dialog8.txtDirectoryToSearch, msg) + Component component78 =null + if(dialog8!=null){ + component78 = dialog8.txtDirectoryToSearch + } + JOptionPane.showMessageDialog(component78, msg) } } else { String msg; @@ -265,7 +294,7 @@ public class LibManager3 { throw new FileNotFoundException(fileToSave.absolutePath) } - IdeaAddFileWithSources withSources = new IdeaAddFileWithSources() + IdeaAddFileWithSources withSources = IdeaAddFileWithSourcesFactory.defaultFactory.createAdded(); // LibConfigurator8 configurator4 = new LibConfigurator8() // String libName = libItem.library.getName(); Runnable r = { @@ -290,14 +319,17 @@ public class LibManager3 { configurator8.assertWriteActionAllowed() log.info "import fine ${fileToSave}" configurator8.commit() + + importFinishedFineUnsafe.run() log.info "${libItem.library.getName()} commit done " + } catch (Throwable e) { - JrrUtilities.showException("Failed import", e); + importFailed.newValue(e) } } } } catch (Throwable e) { - JrrUtilities.showException("Failed import", e); + importFailed.newValue(e); } } Runnable readyCallback = { @@ -306,15 +338,37 @@ public class LibManager3 { LibConfigurator8.submitTr(r); } } catch (Throwable e) { - JrrUtilities.showException("Failed import", e); + importFailed.newValue(e) } } withSources.import2(OSIntegrationIdea.openedProject, fileToSave, readyCallback); } catch (Throwable e) { - JrrUtilities.showException("Failed import", e) + importFailed.newValue(e) } } + public static Runnable importFinishedFineUnsafe = { + Runnable r = { + log.info "sleep for 1 sec .." + Thread.sleep(1000); + DumbService.getInstance(IndexReadyListener.getOpenedProject()).smartInvokeLater { + log.info "index should be ready now" + importFinishedFine.run() + } + } + Thread thread = new Thread(r, 'Sleep after import classpath') + thread.start() + }; + + public static volatile Runnable importFinishedFine = {}; + public static volatile NewValueListener importFailed = new NewValueListener() { + @Override + void newValue(Throwable throwable) { + log.log(Level.SEVERE,"Failed import",throwable) + JrrUtilities.showException("Failed import", throwable); + } + }; + public void runExport(LibItem libItem) { try { // File fileToSave = dialog8.txtDirectoryToSearch.getText() as File diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaRuntimeClasspath.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaRuntimeClasspath.groovy new file mode 100644 index 00000000..7b000eb6 --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaRuntimeClasspath.groovy @@ -0,0 +1,225 @@ +package idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.ideasdk + + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepo +import net.sf.jremoterun.utilities.nonjdk.classpath.UserBintrayRepo +import net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers.ClassPathCalculatorEnumConverter +import net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers.ClassPathCalculatorGroovyWithDownloadWise +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.AllMavenIdsRefs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.KotlinMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds +import net.sf.jremoterun.utilities.nonjdk.compile.IdeaPluginCompiler +import net.sf.jremoterun.utilities.nonjdk.ideadep.LongTaskInfo +import net.sf.jremoterun.utilities.nonjdk.langutils.ObjectStringComparator +import net.sf.jremoterun.utilities.nonjdk.store.Writer3 +import net.sf.jremoterun.utilities.nonjdk.store.Writer4Sub; + +import java.util.logging.Logger; + +/** + * Need keep only idea classes. + * If need non idea classes better pull from public for: 1) have sources, 2) avoid version conflict + */ +@CompileStatic +class IdeaRuntimeClasspath { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + //plugin id : org.jetbrains.kotlin + + public static List acceptFiles = ['openapi.jar', + 'idea.jar', + 'forms_rt.jar', + 'external-system-rt.jar', + 'extensions.jar', + 'credential-store.jar', + 'configuration-store-impl.jar', + 'jshell-protocol.jar', + 'java-impl.jar', 'java-api.jar', 'serviceMessages.jar', 'spellchecker.jar', + 'images.jar', 'Groovy.jar', 'aether-dependency-resolver.jar', + 'jshell-frontend.jar', 'built-in-server.jar', 'bootstrap.jar', 'util.jar', 'groovy_rt.jar', + 'annotations.jar', 'terminal.jar', 'kotlin-plugin.jar', + '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',] + + public static List startwithAccept = ['platform-', 'jps-', 'intellij-', 'idea_', 'randomForestRegressor-', 'sa-jdwp-', + 'rd-', 'jetCheck-', 'java-compatibility-', 'exception-analyzer-api-', + 'groovy-', 'tips-intellij-idea-community-', 'serviceMessages-', '-', '-', '-', '-', '-', '-', '-',] + + + public static List manualMavenIds = [ + new MavenIdAndRepo(new MavenId('org.swinglabs:swingx-core:1.6.2-2'), new UserBintrayRepo('bintray/jcenter')), + new MavenIdAndRepo(new MavenId('msv:isorelax:20050913'), new UserBintrayRepo('bintray/jcenter')), + ] + + // why 'json.jar' was ignored ? + public static List ignoreFiles = ['log4j.jar', + 'jdkAnnotations.jar', 'javac2.jar', 'resources.jar', 'resources_en.jar', + 'trove4j.jar', 'trang-core.jar', 'microba.jar', 'jdom.jar', + 'icons.jar', 'java_resources_en.jar', 'wadl-core.jar', + 'jna.jar', 'servlet-api.jar', 'okhttp.jar', 'http-client.jar', + '', '', '', '', '', '', '', '', '',]; + + public static List startwithIgnore = ['oro-', 'netty-', 'nanoxml-', 'miglayout-', 'jsch-', 'jaxb-', 'batik-', 'netty-', 'cli-', + 'asm-', 'trilead-', 'purejavacomm-', 'pty4j-', 'protobuf-', 'txw2-', 'debugger-memory-agent-', 'stax-ex-', + 'snakeyaml-', 'rngom-', 'proxy-vole-', 'minlog-', 'dbus-', 'swingx-core-', + 'markdownj-core-', 'jediterm-', 'jaxen-', 'jbcrypt-', 'xmlrpc-', 'winp', 'java-utils-', + 'jackson-databind-', 'istack-commons-runtime-', 'isorelax-', 'ion-java-', + 'ini4j-', 'imageio-', 'httpmime-', 'fluent-hc-', 'FastInfoset-', 'delight-rhino-sandbox-', + 'commons-', 'streamex-', 'common-', 'aapt-proto-', 'assertj-core-', 'automaton-', + 'guava-', 'gson-', 'nosyncbuilder-', 'protos-', 'xercesImpl-', 'aapt2-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',] + + public static List addMavenIds = [ + KotlinMavenIds.reflect, KotlinMavenIds.stdlib, KotlinMavenIds.stdlib_jdk8, + LatestMavenIds.jdom, + LatestMavenIds.trove4jIdea, + LatestMavenIds.httpClient, + ] + + + public List unknownFiles = [] + + public static List ignoreMavenGroupIds = [ + 'org.ow2.asm', + 'org.slf4j', + 'stax', + 'xerces', + 'xml-apis', + 'xml-resolver', + 'org.javassist', + 'org.hamcrest', +// 'org .eclipse.jdt', +// 'org.eclipse.xtend', +// 'org.eclipse.xtext', + 'org.codehaus.groovy', + 'org.apache.velocity', + 'org.apache.ws.xmlrpc', + 'org.codehaus.plexus', + 'org.glassfish.jaxb', + 'org.jetbrains.jediterm', + 'org.jetbrains.pty4j', + 'com.sun.activation', + 'javax.xml.bind', + 'com.sun.activation', + 'javax.annotation', + '', + //'org.apache.httpcomponents', + ] + + public ClassPathCalculatorGroovyWithDownloadWise mavenIdSearcher = new ClassPathCalculatorGroovyWithDownloadWise(new LongTaskInfo()); + public AllMavenIdsRefs listOfAllEnums = new AllMavenIdsRefs(); + public ClassPathCalculatorEnumConverter mavenId2EnumConverter; + public String generatedClassNameIdea = 'ideaRuntimeGen' + public File ideaDir1; + + @Deprecated + IdeaRuntimeClasspath() { + + } + + IdeaRuntimeClasspath(File ideaDir1) { + this.ideaDir1 = ideaDir1 + } + + void doAllStuff(File ideaDir) { + ideaDir1 = ideaDir; + } + + void doAllStuff() { + addIdeaFiles(ideaDir1, mavenIdSearcher.addFilesToClassLoaderGroovySave); + mavenIdSearcher.calcAndSave(); + createMavenId2EnumConverter() + mavenId2EnumConverter.filesAndMavenIds.addAll(filterFiles(mavenIdSearcher.filesAndMavenIds)); + mavenId2EnumConverter.calcClassPathFromFiles12(); + mavenId2EnumConverter.sortElements() +// List filesAndMavenIds = mavenId2EnumConverter.filesAndMavenIds +// Collections.sort(filesAndMavenIds, new ObjectStringComparator()) +// mavenId2EnumConverter.filesAndMavenIds = filesAndMavenIds + } + + void createMavenId2EnumConverter() { + mavenId2EnumConverter = new ClassPathCalculatorEnumConverter(listOfAllEnums) { + @Override + Writer4Sub createWriter2() { + Writer4Sub writer4Sub = super.createWriter2() + writer4Sub.classNameGenerated = generatedClassNameIdea + return writer4Sub; + } + } + mavenId2EnumConverter.objectWriter + } + + List filterFiles(List files) { + files = files.collect { filterOnEntity1(it) } + files = files.collect { filterOnEntity2(it) } + return files; + } + + Object filterOnEntity1(Object obj) { + if (obj instanceof File) { + String name1 = obj.getName() + if (name1.startsWith('kotlin-')) { + + name1 = name1.replace('.jar', '') +// name1.re + KotlinMavenIds kotlinMavenId1 = KotlinMavenIds.all.find { it.m.artifactId == name1 } + if (kotlinMavenId1 != null) { + return kotlinMavenId1; + } + if(ideaDir1.child('lib').isChildFile(obj)){ + return null; + } + } + } + return obj; + } + + Object filterOnEntity2(Object obj) { + if (obj instanceof File) { + if (needAcceptFile(obj, obj.getName())) { + return obj + } else { + return null + } + } + if (obj instanceof MavenId) { + if (ignoreMavenGroupIds.contains(obj.groupId)) { + return null; + } + return obj; + } + return obj + } + + + boolean needAcceptFile(File file, String name) { + String acceptt = startwithAccept.find { name.startsWith(it) } + if (acceptt != null) { + return true; + } + if (acceptFiles.contains(name)) { + return true; + } + if (ignoreFiles.contains(name)) { + return false; + } + String ignorrr = startwithIgnore.find { name.startsWith(it) } + if (ignorrr != null) { + return false; + } + return onUnknownFile(file); + } + + boolean onUnknownFile(File f) { + unknownFiles.add(f) + return true + } + + static void addIdeaFiles(File ideaDir, AddFilesToClassLoaderGroovy adder) { + IdeaPluginCompiler.addIdeaCp(adder,ideaDir) + } + + +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaSdkAddSourcesUtils.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaSdkAddSourcesUtils.groovy index aa8bcf97..4d8ca53a 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaSdkAddSourcesUtils.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaSdkAddSourcesUtils.groovy @@ -1,14 +1,17 @@ package idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.ideasdk import com.intellij.openapi.projectRoots.ProjectJdkTable +import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl import idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.LibConfigurator8 import idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.LibItem import idea.plugins.thirdparty.filecompletion.jrr.librayconfigurator.LibManager3; import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.NewValueListener +import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences -import net.sf.jremoterun.utilities.nonjdk.git.GitRef; + +import net.sf.jremoterun.utilities.nonjdk.idea.IdeaMavenRepoParser; import java.util.logging.Logger; import groovy.transform.CompileStatic; @@ -19,6 +22,8 @@ class IdeaSdkAddSourcesUtils { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static ClRef ideaJdkCl = new ClRef('org.jetbrains.idea.devkit.projectRoots.IdeaJdk') + // public static List sourcesJterm = [ // GitReferences.jtermSrc, // GitReferences.jtermPty.refToSourceOnly, @@ -27,9 +32,15 @@ class IdeaSdkAddSourcesUtils { static ProjectJdkImpl findIdeaSdk() { - return ProjectJdkTable.getInstance().getAllJdks().find { - it.sdkType.class.name == 'org.jetbrains.idea.devkit.projectRoots.IdeaJdk' - } as ProjectJdkImpl + Sdk[] jdks = ProjectJdkTable.getInstance().getAllJdks() + Sdk sdkFound = jdks.find { + return isSdkMatched(it) + } + return sdkFound as ProjectJdkImpl + } + + static boolean isSdkMatched(com.intellij.openapi.projectRoots.Sdk sdk){ + return sdk.getSdkType().getClass().getName() == ideaJdkCl.getName() } static void addMavenIdsSourcesToIdeaSdk(List items) { @@ -44,6 +55,21 @@ class IdeaSdkAddSourcesUtils { }) } + static void addIdeaSrc(){ + IdeaSdkToLibAdapterRead read = new IdeaSdkToLibAdapterRead() + read.projectJdk = findIdeaSdk() + LibItem libItem = new LibItem(read); + LibManager3.addCustomAny(libItem, new NewValueListener() { + @Override + void newValue(LibConfigurator8 libConfigurator8) { + File f = new IdeaMavenRepoParser().downloadIdeaSource(null) + libConfigurator8.addSourceF(f); + } + }) + + //IdeaMavenRepoParser + } + static void addSourcesToIdeaSdk() { IdeaSdkToLibAdapterRead read = new IdeaSdkToLibAdapterRead() read.projectJdk = findIdeaSdk() diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaSdkToLibAdapterRead.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaSdkToLibAdapterRead.groovy index 6da7ed31..0f5d7bca 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaSdkToLibAdapterRead.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/jrr/librayconfigurator/ideasdk/IdeaSdkToLibAdapterRead.groovy @@ -47,6 +47,11 @@ class IdeaSdkToLibAdapterRead implements Library { return projectJdk.name } + //@Override + String getPresentableName() { + return getName() + } + @Override String[] getUrls(@NotNull OrderRootType rootType) { return projectJdk.getRoots(rootType).toList().collect { it.toString() }.toArray(new String[0]) @@ -94,6 +99,11 @@ class IdeaSdkToLibAdapterRead implements Library { } + boolean hasSameContent(@NotNull Library library) { + log.info "has same content lib ${library}" + return false + } + @Override void dispose() { diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/share/IdeaReBuilder.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/share/IdeaReBuilder.groovy new file mode 100644 index 00000000..3e2f1de6 --- /dev/null +++ b/src-idea/idea/plugins/thirdparty/filecompletion/share/IdeaReBuilder.groovy @@ -0,0 +1,132 @@ +package idea.plugins.thirdparty.filecompletion.share + +import com.intellij.history.LocalHistory +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.compiler.CompileContext +import com.intellij.openapi.compiler.CompileStatusNotification +import com.intellij.openapi.compiler.CompilerBundle +import com.intellij.openapi.compiler.CompilerManager +import com.intellij.openapi.compiler.JavaCompilerBundle +import com.intellij.openapi.project.Project +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.ObjectWrapper + +import javax.swing.SwingUtilities; +import java.util.logging.Logger; + +@CompileStatic +class IdeaReBuilder { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public final Project project + private final Object lock = new Object() + public volatile boolean aborted2 = false; + public volatile int errors2 = -1; + + public volatile Throwable exception; + public final int maxWait = 3600_000 + + + IdeaReBuilder() { + project = OSIntegrationIdea.getOpenedProject() + } + + void rebuild() { + synchronized (lock) { + SwingUtilities.invokeLater { + try { + rebuildImpl() + } catch (Throwable e) { + exception = e + log.warn("build failed", e); + JrrUtilities.showException("build failed", e); + resultReady() + } + + } + lock.wait(maxWait) + } + if(exception!=null){ + Exception e = new Exception(exception.toString()); + e.setStackTrace(exception.getStackTrace()); + throw e; + } + log.info "errors : ${errors2} , aborted : ${aborted2}" + if (aborted2) { + throw new Exception("aborted") + } + if (errors2 > 0) { + throw new Exception("errors : ${errors2}") + } + } + + private void resultReady() { + synchronized (lock) { + lock.notifyAll() + } + } + + void rebuildImpl() { + Runnable rebuildingImplR = { + try { + log.info "rebuilding" + CompilerManager.getInstance(project).rebuild(new CompileStatusNotificationMy()); + log.info "rebuild all done" + } catch (Throwable e) { + exception = e + log.warn("build failed", e); + JrrUtilities.showException("build failed", e); + resultReady() + } + } + + Runnable saveAll = { + try { + log.info("saving project ..") + OSIntegrationIdea.saveAllImpl2() + log.info("project saved") + JrrIdeaUtils.submitTr(rebuildingImplR) + } catch (Throwable e) { + exception = e; + resultReady() + throw e; + } + } + Runnable refreshImpl = { + try { + log.info "refreshing all ..." + OSIntegrationIdea.refreshImpl() + log.info "refreshing all done" + JrrIdeaUtils.submitTr(saveAll) + } catch (Throwable e) { + exception = e; + resultReady() + throw e; + } + } + JrrIdeaUtils.submitTr refreshImpl + } + + + class CompileStatusNotificationMy implements CompileStatusNotification { + @Override + public void finished(boolean aborted, int errors, int warnings, + final CompileContext compileContext) { + aborted2 = aborted + errors2 = errors; + if (aborted || project.isDisposed()) { + return; + } + + String text = ""; + LocalHistory.getInstance().putSystemLabel(project, errors == 0 + ? JavaCompilerBundle.message("rebuild.lvcs.label.no.errors", text) + : JavaCompilerBundle.message("rebuild.lvcs.label.with.errors", text)); + log.info "compilation finished" + resultReady() + } + } + +} diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/share/Ideasettings/IdeaJavaRunner2Settings.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/share/Ideasettings/IdeaJavaRunner2Settings.groovy index 42f04e6d..8febe51d 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/share/Ideasettings/IdeaJavaRunner2Settings.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/share/Ideasettings/IdeaJavaRunner2Settings.groovy @@ -1,6 +1,8 @@ package idea.plugins.thirdparty.filecompletion.share.Ideasettings import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs2 import net.sf.jremoterun.utilities.nonjdk.idea.set2.SettingsRef @@ -40,4 +42,12 @@ class IdeaJavaRunner2Settings { } + static String buildJavaAgentPath(){ + File jrrCopy = JrrStarterJarRefs2.jremoterun.resolveToFile() + assert jrrCopy.exists() + String path2 = jrrCopy.getAbsolutePath().replace('\\','/') + return "-javaagent:${path2}" + + } + } diff --git a/src-idea/idea/plugins/thirdparty/filecompletion/share/OSIntegrationIdea.groovy b/src-idea/idea/plugins/thirdparty/filecompletion/share/OSIntegrationIdea.groovy index 5026feec..e5c7d790 100644 --- a/src-idea/idea/plugins/thirdparty/filecompletion/share/OSIntegrationIdea.groovy +++ b/src-idea/idea/plugins/thirdparty/filecompletion/share/OSIntegrationIdea.groovy @@ -34,6 +34,7 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.JrrUtils import net.sf.jremoterun.utilities.DefaultObjectName import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.ObjectWrapper import net.sf.jremoterun.utilities.OsInegrationClientI import org.apache.log4j.LogManager @@ -64,48 +65,15 @@ public class OSIntegrationIdea implements DefaultObjectName, OsInegrationClientI return OsInegrationClientI.objectName; } + public static boolean runInNewThread = true; + @Override public void buildAllProjects() throws Exception { - ObjectWrapper aborted2 = new ObjectWrapper<>(false); - ObjectWrapper errors2 = new ObjectWrapper<>(0); - Project project = OSIntegrationIdea.openedProject - invokeAndWaitInSwingThread { - ApplicationManager.getApplication().runWriteAction { - log.info "refreshing all ..." - refreshAll(); - log.info "refreshing all done" - log.info "rebuilding" - CompilerManager.getInstance(project).rebuild(new CompileStatusNotification() { - @Override - public void finished(boolean aborted, int errors, int warnings, - final CompileContext compileContext) { - aborted2.object = aborted - errors2.object = errors; - if (aborted || project.isDisposed()) { - return; - } - - String text = ""; - LocalHistory.getInstance().putSystemLabel(project, errors == 0 - ? CompilerBundle.message("rebuild.lvcs.label.no.errors", text) - : CompilerBundle.message("rebuild.lvcs.label.with.errors", text)); - log.info "compilation finished" - } - }); - log.info "rebuild all done" - - } - } - log.info "errors : ${errors2.object} , aborted : ${aborted2.object}" - if(aborted2.object){ - throw new Exception("aborted") - } - int erros3 =errors2.object as int; - if(erros3>0){ - throw new Exception("errors : ${erros3}") - } + IdeaReBuilder reBuilder = new IdeaReBuilder(); + reBuilder.rebuild() } + DumbService getDumbService() { DumbService.getInstance(getOpenedProject()) } @@ -113,8 +81,7 @@ public class OSIntegrationIdea implements DefaultObjectName, OsInegrationClientI void refreshAll() { invokeAndWaitInSwingThread { - SaveAndSyncHandler.getInstance().refreshOpenFiles(); - VirtualFileManager.getInstance().syncRefresh() + refreshImpl() } } @@ -382,6 +349,12 @@ public class OSIntegrationIdea implements DefaultObjectName, OsInegrationClientI JrrIdeaUtils.submitTr(r) } + static VirtualFile conevertFileToVirtual(File file){ + VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file); + return virtualFile; + } + + @Override public void openFile(File file, String s) throws Exception { if (!file.exists()) { diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/AddJrrLibToCommonIdeaClassloader2.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/AddJrrLibToCommonIdeaClassloader2.groovy index 5fc3d1ed..80977632 100644 --- a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/AddJrrLibToCommonIdeaClassloader2.groovy +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/AddJrrLibToCommonIdeaClassloader2.groovy @@ -1,10 +1,14 @@ package net.sf.jremoterun.utilities.nonjdk.idea import com.intellij.ide.plugins.cl.PluginClassLoader +import com.intellij.util.lang.UrlClassLoader import groovy.transform.CompileStatic import net.sf.jremoterun.JrrUtils import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.UrlToFileConverter +import net.sf.jremoterun.utilities.nonjdk.idea.init.IdeaClasspathAdd +import java.nio.file.Path import java.util.logging.Logger /** @@ -33,7 +37,18 @@ public class AddJrrLibToCommonIdeaClassloader2 { URL classLocation = JrrUtils.getClassLocation(JrrUtils); log.info "JrrUtils location : ${classLocation}" - JrrClassUtils.invokeJavaMethod(classLoader3, "addURL", classLocation); + boolean added = false; + if(classLoader3 instanceof UrlClassLoader){ + if(IdeaClasspathAdd.addFileMethod!=null){ + File f = UrlToFileConverter.c.convert(classLocation); + List paths = [f.toPath()]; + IdeaClasspathAdd.addFileMethod.invoke(classLoader3,paths); + added = true; + } + } + if(!added) { + JrrClassUtils.invokeJavaMethod(classLoader3, "addURL", classLocation); + } log.info("AddJrrLibToCommonIdeaClassloader done"); } diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/CurrentIdeaVersionUtils.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/CurrentIdeaVersionUtils.groovy new file mode 100644 index 00000000..685c8436 --- /dev/null +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/CurrentIdeaVersionUtils.groovy @@ -0,0 +1,26 @@ +package net.sf.jremoterun.utilities.nonjdk.idea + +import com.intellij.openapi.application.ex.ApplicationInfoEx +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class CurrentIdeaVersionUtils { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static String findCurrentIdeaVersion() { + ApplicationInfoEx appInfo = ApplicationInfoEx.getInstanceEx() + return appInfo.getFullVersion() + } + + + static String findCurrentIdeaVersionExtended() { + ApplicationInfoEx appInfo = ApplicationInfoEx.getInstanceEx() + int[] components = appInfo.getBuild().getComponents() + return components.toList().join('.') + } + + + +} diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/CustomRunners.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/CustomRunners.groovy index 0f13f9d6..8186424a 100644 --- a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/CustomRunners.groovy +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/CustomRunners.groovy @@ -47,7 +47,12 @@ class CustomRunners { JPanel panel2 = new JPanel(new FlowLayout()) JButton refreshButton = new JButton("Refresh") refreshButton.addActionListener { - refresh(panel2) + refreshButton.setEnabled(false) + try { + refresh(panel2) + }finally{ + refreshButton.setEnabled(true) + } } refresh(panel2) JPanel panel = createCustomRunners(); @@ -76,6 +81,7 @@ class CustomRunners { JButton button = new JButton(f.name.replace('.groovy', '')) button.addActionListener { osInegrationClient.saveAllEditors() + button.setEnabled(false) Runnable r = { try { log.info "file ${f} calling .." @@ -88,6 +94,10 @@ class CustomRunners { } catch (Throwable e) { log.info "${f} ${e}" JrrUtilities.showException(f.name, e) + }finally{ + SwingUtilities.invokeLater { + button.setEnabled(true) + } } } Thread thread = new Thread(r, "${f.name} custom runner") diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/IdeaMavenRepoParser.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/IdeaMavenRepoParser.groovy new file mode 100644 index 00000000..af66d210 --- /dev/null +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/IdeaMavenRepoParser.groovy @@ -0,0 +1,95 @@ +package net.sf.jremoterun.utilities.nonjdk.idea; + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepo +import net.sf.jremoterun.utilities.nonjdk.classpath.MavenRepositoriesEnum +import net.sf.jremoterun.utilities.nonjdk.ivy.IvyDepResolver3 +import net.sf.jremoterun.utilities.nonjdk.ivy.ManyReposDownloaderImpl +import org.apache.ivy.core.report.ResolveReport +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import org.jsoup.select.Elements; + +import java.util.logging.Logger; + +@CompileStatic +class IdeaMavenRepoParser { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static URL ideaRepo = new URL(MavenRepositoriesEnum.jetbrainsIdea.url) + + public String searchAllWithSources = 'a[href$=-sources.jar]' + public String searchAllPoms = 'a[href$=.pom]' + public String defaultSearchPattern = searchAllPoms + public String pageText; + public List foundMavenIds; + + IdeaMavenRepoParser() { + this(ideaRepo.text) + } + + IdeaMavenRepoParser(String pageText) { + this.pageText = pageText + } + + static MavenIdAndRepo buildIdeaSourcesMavenId(String ideaVersion) { + MavenId m = new MavenId('com.jetbrains.intellij.idea', 'ideaIC', ideaVersion); + return new MavenIdAndRepo(m, MavenRepositoriesEnum.jetbrainsIdea) + } + + List findCurrentVersions() { + String extended = CurrentIdeaVersionUtils.findCurrentIdeaVersionExtended() + return foundMavenIds.findAll { it.version == extended } + } + + /** + * @param ideaVersion like 2020.1 + */ + static File downloadIdeaSource(String ideaVersion) { + if (ideaVersion == null) { + ideaVersion = CurrentIdeaVersionUtils.findCurrentIdeaVersion() + } + IvyDepResolver3 repo = ManyReposDownloaderImpl.createRepo(MavenRepositoriesEnum.jetbrainsIdea) as IvyDepResolver3 + MavenId m = new MavenId('com.jetbrains.intellij.idea', 'ideaIC', ideaVersion); + ResolveReport rr = repo.downloadCustomPackage(m, IvyDepResolver3.sourcesS) + List files = repo.extractFilesFromReport(rr) + if (files.size() == 0) { + throw new FileNotFoundException("failed download source for ${m}") + } + return files[0]; + } + + Elements findEls(Document doc1) { + return doc1.select(defaultSearchPattern) + } + + void findMavenIds() { + Document doc = Jsoup.parse(pageText); + Elements els = findEls(doc) + String repoS = ideaRepo.toString(); + if (!repoS.endsWith('/')) { + repoS += '/' + } + List ll = els.collect { it.attr('href') }.collect { it.replace(repoS, '') } + foundMavenIds = ll.collect { buildId(it) } + } + + MavenId buildId(String s) { + List tokenize1 = s.tokenize('/') + tokenize1.remove(tokenize1.size() - 1); + String version = tokenize1.remove(tokenize1.size() - 1); + String artifact = tokenize1.remove(tokenize1.size() - 1); + String group = tokenize1.join('.'); + return new MavenId(group, artifact, version) + } + + List convertMavenIdsToRepo(List mavenIds) { + List mavenIdAndRepos = mavenIds.collect { + new MavenIdAndRepo(it, MavenRepositoriesEnum.jetbrainsIdea) + } + return mavenIdAndRepos + } + +} diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/IdeaRedefineClassloader.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/IdeaRedefineClassloader.groovy index ff0a423d..4eb55437 100644 --- a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/IdeaRedefineClassloader.groovy +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/IdeaRedefineClassloader.groovy @@ -16,15 +16,18 @@ import java.lang.reflect.Method import java.util.logging.Logger @CompileStatic -public class IdeaRedefineClassloader implements Runnable{ +public class IdeaRedefineClassloader implements Runnable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - public static String ideaPluginId + public static String ideaPluginId; + + public static List actionTried = [] + public static List actionFinished = [] public static void redifineClassloader3() throws Exception { - PluginClassLoader pluginClassLoader = JrrClassUtils.currentClassLoader as PluginClassLoader - String pluginId = pluginClassLoader.pluginId.toString() + PluginClassLoader pluginClassLoader = JrrClassUtils.getCurrentClassLoader() as PluginClassLoader + String pluginId = pluginClassLoader.getPluginId().toString() log.info "detected plugin pluginId = ${pluginId}" redifineClassloader2(pluginId) } @@ -35,7 +38,14 @@ public class IdeaRedefineClassloader implements Runnable{ } public static void redifineClassloader() throws Exception { - if(ideaPluginId==null){ + Class ccc = PluginClassLoader; + final CtClass cc = redefineClassloaderImpl(); + JrrJavassistUtils.redefineClass(cc, ccc); + log.info("PluginClassLoader redefine done"); + } + + public static CtClass redefineClassloaderImpl() throws Exception { + if (ideaPluginId == null) { throw new Exception("ideaPluginId not defined") } log.info("PluginClassLoader try to redefine ... "); @@ -46,24 +56,65 @@ public class IdeaRedefineClassloader implements Runnable{ log.info("PluginClassLoader class location : " + JrrUtils.getClassLocation(ccc)); final CtClass cc = JrrJavassistUtils.getClassFromDefaultPool(ccc); final CtMethod method = JrrJavassistUtils.findMethod(ccc, cc, "loadClass", 2); - Method method1 - String values + //Method method1NotUsed; + String customInsert; + String values; try { - method1 = JrrClassUtils.findMethodByCount(ccc,'loadClassFromParents', 2) - values = """ loadClassFromParents(\$1, null) """ - }catch (NoSuchMethodException e){ - log.info "${e}" + try { + actionTried.add(1) + Method method1NotUsed = JrrClassUtils.findMethodByCount(ccc, 'loadClassFromParents', 2) + values = """ loadClassFromParents(\$1, null) """ + assert method1NotUsed.getReturnType().equals(Class) + actionFinished.add(1) + } catch (NoSuchMethodException e) { + try { + actionTried.add(2) + log.info "failed find loadClassFromParents from idea ce 2018 ${e}" + Method method1NotUsed = JrrClassUtils.findMethodByCount(ccc, 'processResourcesInParents', 5) + values = """ (Class) processResourcesInParents(\$1, this.loadClassInPluginCL, this.loadClassInCl,null, (Object)null) """ + actionFinished.add(2) + } catch (NoSuchMethodException e2) { + try { + actionTried.add(3) + Method method1NotUsed = JrrClassUtils.findMethodByCount(ccc, 'processResourcesInParents', 6) + values = """ (Class) processResourcesInParents(\$1, this.loadClassInPluginCL, this.loadClassInCl, null, (Object)null, true) """ + actionFinished.add(3) + } catch (NoSuchMethodException e3) { + // idea 2021.1 + actionTried.add(20211) + Method method1NotUsed = JrrClassUtils.findMethodByCount(ccc, 'getAllParents', 0) + assert ClassLoader[] == method1NotUsed.getReturnType() + customInsert = """ +ClassLoader[] allParents123 = this.getAllParents(); +for (int i=0 ; i + + + + */ + +@CompileStatic +class ReloadClassIdeaToolbar { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static Icon icon = IconLoader.getIcon('/icon/idea/reload_class.png', ReloadClassIdeaToolbar); + public static String panelNameReloadClass = 'Reload class' + private ClRef reloadClassMenuRef = new ClRef('idea.plugins.thirdparty.filecompletion.share.ReloadClassAction'); + + + + + static void createReloadClassToolbacr(ReloadClassConnectionPanel panel2) { +// JPanel panel = JrrIdeaBeanCommon.bean.reloadClassToolbar +// if (panel != null) { +// return panel +// } + Project project = getOpenedProject() + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project) +// panel = new JPanel(new BorderLayout()) + ToolWindow window = toolWindowManager.registerToolWindow(panelNameReloadClass, panel2.panel, ToolWindowAnchor.RIGHT); + JrrIdeaBeanCommon.bean.reloadClassToolWindow = window + JrrIdeaBeanCommon.bean.reloadClassToolbar = panel2 + window.icon = icon + } + + + static Project getOpenedProject() { + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + if (openProjects == null || openProjects.length == 0) { + throw new IllegalStateException("Can't find open project"); + } + return openProjects[0]; + + } + + +} diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/classpathtester/IdeaClassPathRuntimeTester.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/classpathtester/IdeaClassPathRuntimeTester.groovy new file mode 100644 index 00000000..e0d04ace --- /dev/null +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/classpathtester/IdeaClassPathRuntimeTester.groovy @@ -0,0 +1,74 @@ +package net.sf.jremoterun.utilities.nonjdk.idea.classpathtester + +import com.intellij.ide.plugins.cl.PluginClassLoader +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.nonjdk.classpath.tester.ClassPathTesterHelper2 +import net.sf.jremoterun.utilities.nonjdk.groovy.ExtentionMethodChecker2 +import net.sf.jremoterun.utilities.nonjdk.idea.init.IdeaClasspathAdd +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollector +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollectorI + + +import java.util.logging.Logger; + +@CompileStatic +class IdeaClassPathRuntimeTester{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ClassPathTesterHelper2 helper + + IdeaClassPathRuntimeTester(ClassPathTesterHelper2 helper) { + this.helper = helper + } + + IdeaClassPathRuntimeTester(ProblemCollectorI problemCollector) { + helper = new ClassPathTesterHelper2(problemCollector) + } + + + public ClRef ideaBaseClassloader = new ClRef('com.intellij.util.lang.UrlClassLoader') + public ClRef ideaBaseClassloader20211 = new ClRef('com.intellij.util.lang.PathClassLoader') + + + static void runChecks(){ + ProblemCollector problemCollector = new ProblemCollector() + IdeaClassPathRuntimeTester tester = new IdeaClassPathRuntimeTester(problemCollector) + tester.checker() + boolean allGood = problemCollector.checkIfProblemExistAndShowException() + try { + ExtentionMethodChecker2.check() + }catch(Throwable e){ + log.info ("ExtentionMethodChecker2 failed ",e) + JrrUtilities.showException("ExtentionMethodChecker2 failed ",e) + } + log.info "all good ? : ${allGood}" + } + + void checker() { + ClassLoader classLoaderParent = JrrClassUtils.getCurrentClassLoader().getClass().getClassLoader() + String className1 = classLoaderParent.getClass().getName() + if (className1 != ideaBaseClassloader.className && className1 != ideaBaseClassloader20211.className) { + helper.addProblem(null, "Strange classloader : ${classLoaderParent}") + } else { + checkImpl() + } + } + + void checkImpl() { + PluginClassLoader currentClassLoader = IdeaClasspathAdd.pluginClassLoader + + helper.checkNotSameClassLoader5(new ClRef('org.apache.log4j.Logger'), currentClassLoader) + helper.checkNotSameClassLoader5(new ClRef('org.apache.commons.logging.LogFactory'), currentClassLoader) + helper.checkNotSameClassLoader5(new ClRef('org.slf4j.LoggerFactory'), currentClassLoader) +// helper.checkNotSameClassLoader5(new ClRef('javassist.ClassPath'), currentClassLoader) + helper.checkNotSameClassLoader5(new ClRef('com.sun.jna.Callback'), currentClassLoader) + helper.checkNotSameClassLoader5(GroovyObject, currentClassLoader) + helper.checkNotSameClassLoader5(new ClRef('sun.jvmstat.monitor.HostIdentifier'), currentClassLoader) + helper.checkNotSameClassLoader5(new ClRef('org.codehaus.groovy.runtime.DefaultGroovyMethods'), currentClassLoader) + + } + +} diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/AddFilesToClassLoaderGroovyIdea.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/AddFilesToClassLoaderGroovyIdea.groovy new file mode 100644 index 00000000..cc87ba40 --- /dev/null +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/AddFilesToClassLoaderGroovyIdea.groovy @@ -0,0 +1,17 @@ +package net.sf.jremoterun.utilities.nonjdk.idea.init + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy; + +import java.util.logging.Logger; + +@CompileStatic +class AddFilesToClassLoaderGroovyIdea extends AddFilesToClassLoaderGroovy{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void addFileImpl(File file) throws Exception { + IdeaClasspathAdd.addFileToClassLoader(file) + } +} diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClassLoadWarmup.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClassLoadWarmup.groovy new file mode 100644 index 00000000..c85214de --- /dev/null +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClassLoadWarmup.groovy @@ -0,0 +1,40 @@ +package net.sf.jremoterun.utilities.nonjdk.idea.init + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef; + +import java.util.logging.Logger; + +@CompileStatic +class IdeaClassLoadWarmup { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static List tryLoadClasses = [] + public static volatile int lastIdused =1; + public static ClassLoader classLoaderToWarmup = IdeaClassLoadWarmup.getClassLoader() + + static void initideacl() { + lastIdused++; + initideacl2(lastIdused); + } + + static void initideacl2(int id) { + try { + ClRef jfeeObject = new ClRef('org.jfree.data.ComparableObjectItem') + tryLoadClasses.add(jfeeObject.className) + jfeeObject.loadClass(classLoaderToWarmup) + } catch (Throwable e) { + log.info "${e}" + } + + try { + String className2 = "nosuchpackage.random.packa${id}.nusuchfile${id}" + tryLoadClasses.add(className2) + classLoaderToWarmup.loadClass(className2) + } catch (Throwable e) { + } + } + + +} diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClassPathSettings.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClassPathSettings.groovy index abe9019a..231c3a04 100644 --- a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClassPathSettings.groovy +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClassPathSettings.groovy @@ -1,16 +1,13 @@ -package net.sf.jremoterun.utilities.nonjdk.idea.init; - -import net.sf.jremoterun.utilities.JrrClassUtils; -import java.util.logging.Logger; -import groovy.transform.CompileStatic; +package net.sf.jremoterun.utilities.nonjdk.idea.init +import groovy.transform.CompileStatic @CompileStatic class IdeaClassPathSettings { - private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); public static String customScriptProperty = "idea.custom.init" public static String pluginCLassloaderId = "pluginclassloaderId" + public static String ideaInitGroovyScriptName = "idea.groovy" } diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClasspathAdd.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClasspathAdd.groovy index 276c06b8..24d2deee 100644 --- a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClasspathAdd.groovy +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init/IdeaClasspathAdd.groovy @@ -8,12 +8,17 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunner +import net.sf.jremoterun.utilities.groovystarter.JrrStarterVariables import net.sf.jremoterun.utilities.groovystarter.st.SetConsoleOut2 + +import java.lang.reflect.Method +import java.nio.file.Path +import java.util.logging.Level import java.util.logging.Logger @CompileStatic -public class IdeaClasspathAdd { +public class IdeaClasspathAdd implements GroovyObject{ private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); @@ -23,61 +28,106 @@ public class IdeaClasspathAdd { public static PluginClassLoader pluginClassLoader = (PluginClassLoader) JrrClassUtils.getCurrentClassLoader(); - public static AddFilesToClassLoaderGroovy addCl = new AddFilesToClassLoaderGroovy() { - @Override - public void addFileImpl(File file) throws Exception { - addFileToClassLoader(file) - } - }; + public static List traceFlags = []; + public static File ideaInitScriptDebug; + + public static AddFilesToClassLoaderGroovyIdea addCl = new AddFilesToClassLoaderGroovyIdea(); + public static boolean addFileMethodTriedFind =false; + public static Method addFileMethod; static void addFileToClassLoader(File file){ - pluginClassLoader.addURL(file.toURL()); + if(addFileMethod==null){ + if(addFileMethodTriedFind){ + + }else { + addFileMethodTriedFind = true + try { + addFileMethod = JrrClassUtils.findMethodByCount(pluginClassLoader.getClass(), 'addFiles', 1); + }catch(NoSuchMethodException e){ + log.log(Level.INFO,"failed find addFiles method",e) + } + } + } + if(addFileMethod==null){ + pluginClassLoader.addURL(file.toURL()); + }else { + List paths = [file.toPath()] + addFileMethod.invoke(pluginClassLoader,paths) + } } public static void init() throws Exception { inited = true; + traceFlags.add 710; + //net.sf.jremoterun.utilities.java11.Java11ModuleSetDisable.doIfNeeded() + traceFlags.add 711; SharedObjectsUtils.getClassLoaders().put(IdeaClassPathSettings.pluginCLassloaderId, pluginClassLoader); + traceFlags.add 720; SimpleFindParentClassLoader.setDefaultClassLoader(pluginClassLoader); + traceFlags.add 730; log.info("classes added fine"); initThread = Thread.currentThread(); SetConsoleOut2.setConsoleOutIfNotInited(); + traceFlags.add 740; runScriptInUserDir() + traceFlags.add 750; runCustom() + traceFlags.add 760; } static void runScriptInUserDir() { - File userHome = System.getProperty('user.home') as File - if (userHome.exists()) { - File scriptInUserDir = new File(userHome, 'jrr/configs/idea.groovy') - if (scriptInUserDir.exists()) { - log.info("running ${scriptInUserDir} .."); - Script parse = GroovyMethodRunner.groovyScriptRunner.groovyShell.parse(scriptInUserDir) + if(JrrStarterVariables.filesDir==null){ + traceFlags.add 410; + log.severe "files dir is null" + JrrUtilities.showException("files dir is null",new Exception("files dir is null")); + }else{ + ideaInitScriptDebug = new File(JrrStarterVariables.filesDir,IdeaClassPathSettings.ideaInitGroovyScriptName); + if(ideaInitScriptDebug.exists()){ + traceFlags.add 420; + if(JrrStarterVariables.classesDir!=null){ + traceFlags.add 430; + if(JrrStarterVariables.classesDir.exists()){ + addCl.addF JrrStarterVariables.classesDir + }else{ + log.error("file not exit : ${JrrStarterVariables.classesDir}") + } + + } + log.info("running ${ideaInitScriptDebug} .."); + Script parse = GroovyMethodRunner.groovyScriptRunner.groovyShell.parse(ideaInitScriptDebug) parse.run() - log.info("finished ${scriptInUserDir}"); + log.info("finished ${ideaInitScriptDebug}"); }else{ - log.info "file not exist : ${scriptInUserDir}" + log.severe "file not exist : ${ideaInitScriptDebug}" + traceFlags.add 440; + JrrUtilities.showException("file not exist : ${ideaInitScriptDebug}",new Exception("file not exist : ${ideaInitScriptDebug}")); } - }else{ - log.info "user home not exist : ${userHome}" + traceFlags.add 450; } } static void runCustom() { + traceFlags.add 460; String customScript = System.getProperty(IdeaClassPathSettings.customScriptProperty) if (customScript == null) { + traceFlags.add 470; log.info("property not set : ${IdeaClassPathSettings.customScriptProperty}"); }else{ + traceFlags.add 480; File customScriptF = customScript as File if (customScriptF.exists()) { + traceFlags.add 490; log.info("running ${customScriptF} .."); Script parse = GroovyMethodRunner.groovyScriptRunner.groovyShell.parse(customScriptF) parse.run() log.info("finished ${customScriptF}"); }else{ + traceFlags.add 500; log.info "File not found ${customScript}" JrrUtilities.showException("File not found ${customScript}",new FileNotFoundException("${customScript}")) } + traceFlags.add 510; } } diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit5.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit5.groovy index 996fe91c..1d2aa928 100644 --- a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit5.groovy +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit5.groovy @@ -32,6 +32,9 @@ class IdeaInit5 extends InjectedCode { File gitBaseDir = list.get(0) assert gitBaseDir.exists() File logDir = list.get(1) + if(logDir==null){ + throw new NullPointerException('logDir is null') + } assert logDir.isDirectory() initImpl2(gitBaseDir,logDir) } diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/jrr/JrrIdeaBeanCommon.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/jrr/JrrIdeaBeanCommon.groovy index 25d986f9..4a91be2a 100644 --- a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/jrr/JrrIdeaBeanCommon.groovy +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/jrr/JrrIdeaBeanCommon.groovy @@ -1,6 +1,7 @@ package net.sf.jremoterun.utilities.nonjdk.idea.jrr -import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindow +import idea.plugins.thirdparty.filecompletion.jrr.a.actions.reloadclass.ReloadClassConnectionPanel; import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.jrrbean.JrrBeanMaker @@ -18,7 +19,9 @@ class JrrIdeaBeanCommon { .makeBeanAndRegisterMBeanNoEx(JrrIdeaBeanCommon); JPanel customRunners; + ReloadClassConnectionPanel reloadClassToolbar; + ToolWindow reloadClassToolWindow ToolWindow customRunnersToolWindow } diff --git a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/set2/SettingsRef.groovy b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/set2/SettingsRef.groovy index 78a7c6d8..fb78c244 100644 --- a/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/set2/SettingsRef.groovy +++ b/src-idea/net/sf/jremoterun/utilities/nonjdk/idea/set2/SettingsRef.groovy @@ -3,6 +3,8 @@ package net.sf.jremoterun.utilities.nonjdk.idea.set2 import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.BaseDirSetting import net.sf.jremoterun.utilities.nonjdk.classpath.sl.GroovySettingsLoader import java.util.logging.Level @@ -15,17 +17,19 @@ class SettingsRef { public static IdeaLibManagerConfig config = new IdeaLibManagerConfig(); - public static File location = (System.getProperty('user.home') + '/jrr/idea/libmanager.groovy') as File + public + static ToFileRef2 location = BaseDirSetting.baseDirSetting.childL("idea/libmanager.groovy") - public static File locationEdit = (System.getProperty('user.home') + '/jrr/idea/libmanager_edit.groovy') as File + public + static ToFileRef2 locationEdit = BaseDirSetting.baseDirSetting.childL("idea/libmanager_edit.groovy"); static void loadSettingsS2() { try { - if (location.exists()) { - SettingsRef.loadSettingsS(location) + if (location.resolveToFile().exists()) { + SettingsRef.loadSettingsS(location.resolveToFile()) } } catch (Throwable e) { log.log(Level.SEVERE, "failed load config", e) diff --git a/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaClassPathHook.groovy b/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaClassPathHook.groovy index 1de1a5e8..2955fe70 100644 --- a/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaClassPathHook.groovy +++ b/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaClassPathHook.groovy @@ -3,6 +3,7 @@ package idea.plugins.thirdparty.filecompletion.jrr.classpathhook import com.intellij.execution.configurations.GeneralCommandLine import com.intellij.execution.configurations.JavaCommandLineState import com.intellij.execution.configurations.ParametersList +import com.intellij.execution.runners.ExecutionEnvironment import groovy.transform.CompileStatic import idea.plugins.thirdparty.filecompletion.share.Ideasettings.IdeaJavaRunner2Settings import javassist.CtClass @@ -31,6 +32,7 @@ class JavaClassPathHook extends InjectedCode { }else { inited = true JavaClassPathHook.installHook() + JavaClassPathHookV2.installHook() JavaStartConfigHook.installHook() } } @@ -60,15 +62,16 @@ class JavaClassPathHook extends InjectedCode { JavaCommandLineState commandLineState = obj[0] as JavaCommandLineState; GeneralCommandLine generalCommandLine = obj[1] as GeneralCommandLine - ParametersList parametersList = generalCommandLine.parametersList - log.info "parametersString : ${parametersList.parametersString}" - List list = parametersList.list + ParametersList parametersList = generalCommandLine.getParametersList() + log.info "parametersString : ${parametersList.getParametersString()}" + List list = parametersList.getList() // list IdeaJavaRunner2Settings.jvmOptions.reverse(false).each { parametersList.addAt(0, it) } - String runnerName = commandLineState.environment.toString() + ExecutionEnvironment environment = commandLineState.getEnvironment() + String runnerName = environment.toString() File runnerFile = new File(IdeaJavaRunner2Settings.runners, runnerName) if (!runnerFile.exists()) { log.info "no runner file ${runnerFile}" @@ -76,7 +79,7 @@ class JavaClassPathHook extends InjectedCode { } File libNameAsGroovy = new File(IdeaJavaRunner2Settings.libs, runnerFile.text + '.groovy') if (!libNameAsGroovy.exists()) { - log.info "file not exists ${libNameAsGroovy}" + log.info "file not exists : ${libNameAsGroovy}" return null } diff --git a/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaClassPathHookV2.groovy b/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaClassPathHookV2.groovy new file mode 100644 index 00000000..e6690308 --- /dev/null +++ b/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaClassPathHookV2.groovy @@ -0,0 +1,230 @@ +package idea.plugins.thirdparty.filecompletion.jrr.classpathhook + +import com.intellij.execution.configurations.GeneralCommandLine +import com.intellij.execution.configurations.JavaCommandLineState +import com.intellij.execution.configurations.ParametersList +import com.intellij.execution.runners.ExecutionEnvironment +import com.intellij.execution.target.TargetedCommandLineBuilder +import com.intellij.execution.target.value.CompositeTargetValue +import com.intellij.execution.target.value.DeferredLocalTargetValue +import com.intellij.execution.target.value.DeferredTargetValue +import com.intellij.execution.target.value.TargetValue +import groovy.transform.CompileStatic +import idea.plugins.thirdparty.filecompletion.share.Ideasettings.IdeaJavaRunner2Settings +import javassist.CtClass +import javassist.CtMethod +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.javassist.JrrJavassistUtils +import net.sf.jremoterun.utilities.javassist.codeinjector.CodeInjector +import net.sf.jremoterun.utilities.javassist.codeinjector.InjectedCode +import net.sf.jremoterun.utilities.nonjdk.classpath.UrlCLassLoaderUtils2 +import org.apache.commons.io.FilenameUtils +import org.apache.log4j.LogManager +import org.apache.log4j.Logger +import org.jetbrains.concurrency.AsyncPromise +import org.jetbrains.concurrency.Promise + +import java.util.logging.Level + +@CompileStatic +class JavaClassPathHookV2 extends InjectedCode { + private static final Logger log = LogManager.getLogger(JrrClassUtils.currentClass); + + public static boolean inited = false + + static void installBothHooks() { + if (inited) { + log.info "already inited" + } else { + inited = true + JavaClassPathHookV2.installHook() + JavaStartConfigHook.installHook() + } + } + + @Override + protected Object handleException(Object key, Throwable throwable) { + super.handleException(key, throwable) + JrrUtilities.showException("Can't create java start hook", throwable) + return null + } + + static void installHook() { + Class clazz = com.intellij.execution.configurations.JavaCommandLineState + CtClass ctClass = JrrJavassistUtils.getClassFromDefaultPool(clazz) + CtMethod method = JrrJavassistUtils.findMethod(clazz, ctClass, "createTargetedCommandLine", 2); + method.insertAfter """ + ${CodeInjector.createSharedObjectsHookVar2(clazz)} + ${CodeInjector.myHookVar}.get(new Object[]{this,\$_}); + """ + JrrJavassistUtils.redefineClass(ctClass, clazz); + CodeInjector.putInector2(clazz, new JavaClassPathHookV2()) + } + + static void installHookV2() { + Class clazz = com.intellij.execution.configurations.JavaCommandLineState + CtClass ctClass = JrrJavassistUtils.getClassFromDefaultPool(clazz) + CtMethod method = JrrJavassistUtils.findMethod(clazz, ctClass, "prepareTargetEnvironmentRequest", 3); + method.insertAfter """ + ${CodeInjector.createSharedObjectsHookVar2(clazz)} + ${CodeInjector.myHookVar}.get(new Object[]{this,this.myCommandLine}); + """ + JrrJavassistUtils.redefineClass(ctClass, clazz); + CodeInjector.putInector2(clazz, new JavaClassPathHookV2()) + } + + public static int getTimeout = 1000; +public static boolean useNew = true + + + @Override + Object getImpl(Object key) { + java.lang.Object[] obj = (Object[]) key; + JavaCommandLineState commandLineState = obj[0] as JavaCommandLineState; + TargetedCommandLineBuilder generalCommandLine = obj[1] as TargetedCommandLineBuilder + ArrayList> parametersList = JrrClassUtils.getFieldValue(generalCommandLine, 'myParameters') as ArrayList + //ParametersList parametersList = generalCommandLine.getParametersList() + //log.info "parametersString : ${parametersList.getParametersString()}" + //List list = parametersList.getList() +// list + IdeaJavaRunner2Settings.jvmOptions.reverse(false).each { + parametersList.add(0, new DeferredLocalTargetValue(it)) + } + + ExecutionEnvironment environment = commandLineState.getEnvironment() + String runnerName = environment.toString() + File runnerFile = new File(IdeaJavaRunner2Settings.runners, runnerName) + if (!runnerFile.exists()) { + log.info "no runner file ${runnerFile}" + return null + } + File libNameAsGroovy = new File(IdeaJavaRunner2Settings.libs, runnerFile.text + '.groovy') + if (!libNameAsGroovy.exists()) { + log.info "file not exists : ${libNameAsGroovy}" + return null + } + + int classPathEl = -1; + for (int i = 0; i < parametersList.size(); i++) { + try { + TargetValue elI = parametersList.get(i); + Promise targetValue = elI.getTargetValue() + String value1 = targetValue.blockingGet(getTimeout) + if (value1 == '-classpath') { + classPathEl = i + 1; + log.info "classPathEl = ${classPathEl}" + break; + } + } catch (Exception exception) { + log.info("failed get el ${i}", exception) + } + } + if (classPathEl == -1) { + log.info "classpath el not found" + return null + } + TargetValue elClasspath = parametersList.get(classPathEl) + log.info "elClasspath name = ${elClasspath.getClass().getName()}" + final Promise classpathValue = elClasspath.getTargetValue() + log.info("classpathValue class ${classpathValue.getClass().getName()}") + File myLibsPrefix = createZip7(libNameAsGroovy) + if(useNew) { + if (elClasspath instanceof com.intellij.execution.target.value.DeferredTargetValue) { +// at com.intellij.execution.target.value.DeferredTargetValue.resolve(DeferredTargetValue.java:21) +// at com.intellij.openapi.projectRoots.JdkCommandLineSetup$requestUploadIntoTarget$2.fun(JdkCommandLineSetup.kt:101) +// at org.jetbrains.concurrency.AsyncPromise$then$1.apply(AsyncPromise.kt:125) +// at com.intellij.openapi.projectRoots.JdkCommandLineSetup.provideEnvironment(JdkCommandLineSetup.kt:168) +// at com.intellij.execution.configurations.JavaCommandLineState.handleCreatedTargetEnvironment(JavaCommandLineState.java:141) +// at com.intellij.execution.runners.ExecutionEnvironment.prepareTargetEnvironment(ExecutionEnvironment.java:152) + log.info("resoling manyally") + com.intellij.execution.target.value.DeferredTargetValue dd = elClasspath + String strOld = dd.getLocalValue().blockingGet(getTimeout) as String + log.info "strOld = ${strOld}" + if (strOld.startsWith('@')) { + throw new Exception('Not supported') + } +// dd.resolve('niksomevalue') + String classPathElValue = myLibsPrefix.getAbsolutePath() + File.pathSeparator + strOld; + log.info "classPathElValue after = ${classPathElValue}" + parametersList.set(classPathEl, new DeferredLocalTargetValue(classPathElValue)) + } + }else{ + String classPathElValue = classpathValue.blockingGet(getTimeout) + if (classPathElValue.startsWith('@')) { + throw new Exception('Not supported') + } + log.info "classPathElValue before = ${classPathElValue}" + classPathElValue = myLibsPrefix.getAbsolutePath() + File.pathSeparator + classPathElValue; + log.info "classPathElValue after = ${classPathElValue}" + parametersList.set(classPathEl, new DeferredLocalTargetValue(classPathElValue)) + } +// int index = list.indexOf('-classpath') +// if (index < 0) { +// List all = list.findAll { it.startsWith('@') }.collect { +// it.substring(1) as File +// }.findAll { it.exists() && it.isFile() }.findAll { it.text.readLines()[0] == '-classpath' } +// if(all.size()==1){ +// log.info "seems java9" +// addppendJava9(all.first(),libNameAsGroovy) +// }else { +// log.error("bad index : ${list}") +// } +// } else { +// String classPathJar = list.get(index + 1) +// File file = classPathJar as File +// assert file.exists() +// List classpath = []; +// File myLibsPrefix = createZip7(libNameAsGroovy) +// classpath.add myLibsPrefix +// classpath.add file +// classpath.each { assert it.exists() } +// String newClassPath = classpath.collect { it.absolutePath }.join(';') +// parametersList.set(index + 1, newClassPath) +// } + return null + } + + void addppendJava9(File ideaClassPathFile, File libNameAsGroovy) { + List classpath = []; + AddFilesToClassLoaderGroovy addCl = new AddFilesToClassLoaderGroovy() { + @Override + void addFileImpl(File file33) throws Exception { + classpath.add(file33) + } + } + addCl.addFromGroovyFile(libNameAsGroovy) + + List lines = ideaClassPathFile.text.readLines() + String s = classpath.join(';') + ';' + lines[1] + lines[1] = s + ideaClassPathFile.text = lines.join('\n') + + } + + public static File createZip7(File libNameAsGroovy) throws Exception { + List classpath = []; + AddFilesToClassLoaderGroovy addCl = new AddFilesToClassLoaderGroovy() { + @Override + void addFileImpl(File file33) throws Exception { + classpath.add(file33) + } + } + addCl.addFromGroovyFile(libNameAsGroovy) + classpath = classpath.findAll { it != null }.unique() + File suffix = createZip2(classpath, FilenameUtils.getBaseName(libNameAsGroovy.name)) + return suffix + } + + public static File createZip2(List files, String libName) throws Exception { + byte[] bs = UrlCLassLoaderUtils2.createJarForLoadingClasses(files) + assert IdeaJavaRunner2Settings.jars.exists() + File libFile = new File(IdeaJavaRunner2Settings.jars, libName + '.jar') + libFile.bytes = bs + return libFile + } + + +} diff --git a/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaStartConfigHook.groovy b/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaStartConfigHook.groovy index a19fb5a6..cc000421 100644 --- a/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaStartConfigHook.groovy +++ b/src-idea2/idea/plugins/thirdparty/filecompletion/jrr/classpathhook/JavaStartConfigHook.groovy @@ -52,7 +52,7 @@ class JavaStartConfigHook extends InjectedCode { static void installHook() { Class clazz = SingleConfigurationConfigurable CtClass ctClass = JrrJavassistUtils.getClassFromDefaultPool(clazz) - CtConstructor method = JrrJavassistUtils.findConstructor(ctClass, 2) + CtConstructor method = JrrJavassistUtils.findConstructor( ctClass, 2) method.insertAfter """ ${CodeInjector.createSharedObjectsHookVar2(clazz)} ${CodeInjector.myHookVar}.get(this); @@ -61,13 +61,17 @@ class JavaStartConfigHook extends InjectedCode { JrrJavassistUtils.redefineClass(ctClass, clazz); } + public static boolean doIsokComponentCheck = false; + void getImpl2(Object o) { com.intellij.execution.impl.SingleConfigurationConfigurable c = o as SingleConfigurationConfigurable; SettingsEditor settingsEditor = c.getEditor() JComponent component = settingsEditor.getComponent() log.info "layout 2 ${component.layout} ${c.nameText} ${c.displayName}" - Component component1 = SwingComponentFinder.findComponent(component, this.&isOkCOmponent) - assert component1!=null + if(doIsokComponentCheck) { + Component component1 = SwingComponentFinder.findComponent(component, this.&isOkCOmponent) + assert component1 != null + } Container parent = component.parent; log.info "${parent.layout} " GridBagLayout layout2 = parent.layout as GridBagLayout @@ -88,6 +92,12 @@ class JavaStartConfigHook extends InjectedCode { JPanel createPanel(String runnerName){ JPanel panel =new JPanel(new BorderLayout()) //java.util.List list1= new ArrayList(Arrays.asList( IdeaJavaRunnerSettings.libs.list())) + if(!IdeaJavaRunner2Settings.libs.exists()){ + throw new FileNotFoundException(IdeaJavaRunner2Settings.libs.getAbsolutePath()); + } + if(!IdeaJavaRunner2Settings.libs.isDirectory()){ + throw new IOException("Not a dir : "+IdeaJavaRunner2Settings.libs.getAbsolutePath()); + } java.util.List list1= IdeaJavaRunner2Settings.libs.listFiles().toList().collect {FilenameUtils.getBaseName(it.name)} list1.add(none) File runnerFile = new File(IdeaJavaRunner2Settings.runners, runnerName) diff --git a/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaClassPathTester.groovy b/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaClassPathTester.groovy index 4dfc3089..df4cb4af 100644 --- a/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaClassPathTester.groovy +++ b/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaClassPathTester.groovy @@ -5,23 +5,38 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.nonjdk.classpath.CheckNonCache2 import net.sf.jremoterun.utilities.nonjdk.classpath.tester.ClassPathTesterHelper +import net.sf.jremoterun.utilities.nonjdk.classpath.tester.ClassPathTesterHelper2 +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollectorI +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollectorIThrowImmediate import org.apache.logging.log4j.LogManager import java.util.logging.Logger @CompileStatic -public class IdeaClassPathTester extends ClassPathTesterHelper { +public class IdeaClassPathTester extends ClassPathTesterHelper2 implements Runnable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + IdeaClassPathTester(ProblemCollectorI problemCollector) { + super(problemCollector) + } + + IdeaClassPathTester() { + super(new ProblemCollectorIThrowImmediate()) + } + @Override - public void runImpl() throws Exception { + void run() { + runImpl() + } + + void runImpl() { CheckNonCache2.check(); - checkNoSuchClass(new ClRef( "org.apache.log4j.Logger")); + checkNoSuchClass new ClRef( "org.apache.log4j.Logger"); checkNoSuchClass new ClRef("org.apache.commons.logging.LogFactory"); org.apache.logging.log4j.Logger logger2 = LogManager.getLogger("test"); - checkClassInstanceOf(logger2, org.apache.logging.log4j.core.Logger.class); + checkClassInstanceOf5(logger2, org.apache.logging.log4j.core.Logger.class); checkNoSuchClass new ClRef("org.slf4j.LoggerFactory"); checkNoSuchClass new ClRef("org.slf4j.Logger"); diff --git a/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaCommonInit.groovy b/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaCommonInit.groovy index 2466e73f..d724c6fb 100644 --- a/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaCommonInit.groovy +++ b/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaCommonInit.groovy @@ -1,10 +1,12 @@ package net.sf.jremoterun.utilities.nonjdk.idea +import com.intellij.openapi.extensions.PluginId import groovy.transform.CompileStatic import idea.plugins.thirdparty.filecompletion.jrr.classpathhook.JavaClassPathHook import net.sf.jremoterun.SimpleJvmTiAgent import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.groovystarter.st.SetConsoleOut2 import net.sf.jremoterun.utilities.nonjdk.GeneralUtils import net.sf.jremoterun.utilities.nonjdk.InitGeneral @@ -18,7 +20,7 @@ import java.util.logging.Logger @CompileStatic class IdeaCommonInit implements Runnable { - + //-Dintellij.log.stdout=false private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); static volatile boolean inInit = false; @@ -54,6 +56,18 @@ class IdeaCommonInit implements Runnable { static void init1Impl() { SetConsoleOut2.setConsoleOutIfNotInited(); log.info "in IdeaCommonInit.init1Impl" + ClassLoader log4jClassLoader = org.apache.log4j.Level.getClassLoader(); + log.info "log4jClassLoader = ${log4jClassLoader}" + if (log4jClassLoader instanceof com.intellij.ide.plugins.cl.PluginClassLoader) { + com.intellij.ide.plugins.cl.PluginClassLoader clll = (com.intellij.ide.plugins.cl.PluginClassLoader) log4jClassLoader; + PluginId pluginId = clll.getPluginId(); + log.info "log4jClassLoader classloader for log4j class pluin id ${pluginId} "; + } + if(log4jClassLoader == JrrClassUtils.getCurrentClassLoader()){ + new ClRef('net.sf.jremoterun.utilities.nonjdk.idea.IdeaRedefineClassloader') + throw new Exception("Wrong classloader for log4j class ${log4jClassLoader}") + } + String ideaProxyLoggerName = "#com.intellij.util.proxy.CommonProxy"; setIdeaLogLevel(ideaProxyLoggerName, Level.DEBUG) @@ -73,7 +87,7 @@ class IdeaCommonInit implements Runnable { } GeneralUtils.startLogTimer() - JrrClassUtils.ignoreClassesForCurrentClass.add(com.intellij.util.proxy.CommonProxy.name) + JrrClassUtils.ignoreClassesForCurrentClass.add(com.intellij.util.proxy.CommonProxy.getName()) IdeaSetDependencyResolver3.setDepResolver() proxyLogLayout.additionalIgnore.addAll(ignoreClasses) Log4j2PatternLayout.customLayouts.put(ideaProxyLoggerName, proxyLogLayout) @@ -104,7 +118,7 @@ class IdeaCommonInit implements Runnable { setIdeaLogLevel("#${clazz.name}", level) } - static void setIdeaLogLevel(String loggerName, Level level) { + static void setIdeaLogLevel(String loggerName, org.apache.log4j.Level level) { Log4j2Utils.setLogLevel(loggerName, level) com.intellij.openapi.diagnostic.Logger ll = com.intellij.openapi.diagnostic.Logger.getInstance(loggerName); ll.setLevel(level) diff --git a/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaProxyDisable.groovy b/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaProxyDisable.groovy new file mode 100644 index 00000000..8434db9d --- /dev/null +++ b/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/IdeaProxyDisable.groovy @@ -0,0 +1,23 @@ +package net.sf.jremoterun.utilities.nonjdk.idea + +import groovy.transform.CompileStatic +import javassist.CtClass +import javassist.CtMethod; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.javassist.JrrJavassistUtils; + +import java.util.logging.Logger; + +@CompileStatic +class IdeaProxyDisable { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + void disableIdeaProxy(){ + Class cl = com.intellij.util.proxy.CommonProxy + CtClass pool = JrrJavassistUtils.getClassFromDefaultPool(cl) + CtMethod method = JrrJavassistUtils.findMethod(cl, pool, 'isInstalledAssertion', 0) + method.setBody(null) + JrrJavassistUtils.redefineClass(pool,cl) + } +} diff --git a/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit4.groovy b/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit4.groovy index 2776247a..bc683405 100644 --- a/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit4.groovy +++ b/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit4.groovy @@ -4,11 +4,13 @@ import groovy.transform.CompileStatic import idea.plugins.thirdparty.filecompletion.jrr.InitPlugin2 import net.sf.jremoterun.SimpleFindParentClassLoader import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.nonjdk.LogExitTimeHook import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences import net.sf.jremoterun.utilities.nonjdk.idea.init.IdeaClasspathAdd import net.sf.jremoterun.utilities.nonjdk.log.Log4j2Utils +import java.util.logging.Level import java.util.logging.Logger @CompileStatic @@ -28,7 +30,13 @@ class IdeaInit4 implements Runnable{ }else { inited = true - initImpl() + try { + initImpl() + }catch(Throwable e){ + log.log(Level.SEVERE,"failed init idea ",e); + JrrUtilities.showException("failed init idea ",e); + throw e; + } } } diff --git a/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit6.groovy b/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit6.groovy index 433b26d0..6236877b 100644 --- a/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit6.groovy +++ b/src-idea2/net/sf/jremoterun/utilities/nonjdk/idea/init2/IdeaInit6.groovy @@ -8,6 +8,8 @@ import net.sf.jremoterun.utilities.nonjdk.IfFrameworkResourceDirs import net.sf.jremoterun.utilities.nonjdk.InfocationFrameworkStructure import net.sf.jremoterun.utilities.nonjdk.LogExitTimeHook import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs +import net.sf.jremoterun.utilities.nonjdk.idea.classpathtester.IdeaClassPathRuntimeTester import net.sf.jremoterun.utilities.nonjdk.idea.init.IdeaClasspathAdd import net.sf.jremoterun.utilities.nonjdk.log.Log4j2Utils @@ -24,10 +26,13 @@ class IdeaInit6 implements Runnable{ } static void run2() throws Exception { - InfocationFrameworkStructure.ifDir = GitReferences.ifFramework.resolveToFile() + if(InfocationFrameworkStructure.ifDir==null) { + InfocationFrameworkStructure.ifDir = GitSomeRefs.ifFramework.resolveToFile() + } IdeaClasspathAdd.addCl.addAll IfFrameworkResourceDirs.all IdeaClasspathAdd.addCl.add GitReferences.rsta IdeaClasspathAdd.addCl.add GitReferences.rstaAutoCompetion + IdeaClassPathRuntimeTester.runChecks() } diff --git a/src-idw/net/infonode/properties/propertymap/JrrIdwPropertyMapManager.groovy b/src-idw/net/infonode/properties/propertymap/JrrIdwPropertyMapManager.groovy new file mode 100644 index 00000000..dc964e97 --- /dev/null +++ b/src-idw/net/infonode/properties/propertymap/JrrIdwPropertyMapManager.groovy @@ -0,0 +1,83 @@ +package net.infonode.properties.propertymap + +import groovy.transform.CompileStatic +import net.infonode.properties.propertymap.PropertyMapManager +import net.infonode.util.collection.map.base.ConstMap; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities + +import javax.swing.SwingUtilities; +import java.util.logging.Logger; + +@CompileStatic +class JrrIdwPropertyMapManager extends PropertyMapManager { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static PropertyMapManager propertyMapManagerDefault = getInstance(); + public static JrrIdwPropertyMapManager jrrIdwPropertyMapManager; + + public PropertyMapManager nested + public boolean checkThreadPropAddMapChanges = true + public boolean checkThreadPropOnBegin = false + + + + static void setManager(){ + + if(jrrIdwPropertyMapManager==null) { + jrrIdwPropertyMapManager = new JrrIdwPropertyMapManager() + jrrIdwPropertyMapManager.nested = getInstance(); + JrrClassUtils.setFieldValue(PropertyMapManager, 'INSTANCE',jrrIdwPropertyMapManager) + }else{ + PropertyMapManager propsManager = JrrClassUtils.getFieldValue(PropertyMapManager, 'INSTANCE') as PropertyMapManager + if (propsManager instanceof JrrIdwPropertyMapManager) { + + }else{ + throw new Exception("Strange manager : ${propsManager.getClass()}") + } + } + } + + boolean checkThread() { + if (SwingUtilities.isEventDispatchThread()) { + return true + } + Thread thread = Thread.currentThread() + log.severe("Wrong thread ${thread.getId()} ${thread.getName()}", new Exception("Wrong idw tread : ${thread.getId()} ${thread.getName()}")) + return false + + } + + @Override + void beginBatch() { + if(checkThreadPropOnBegin) { + checkThread() + } + nested.beginBatch() + } + + @Override + void endBatch() { + nested.endBatch() + } + + @Override + void addMapChanges(PropertyMapImpl propertyMap, ConstMap mapChanges) { + if(checkThreadPropAddMapChanges) { + checkThread() + } + try { + nested.addMapChanges(propertyMap, mapChanges) + } catch (Throwable e) { + Thread thread = Thread.currentThread() + try { + + log.severe("failed summary on thread : ${thread.getId()} ${thread.getName()}", e) + log.severe("failed with details on thread : ${thread.getId()} ${thread.getName()} with props: ${propertyMap}, changes: ${mapChanges} with ex: ${e}") + JrrUtilities.showException("failed on thread : ${thread.getId()} ${thread.getName()}", e) + }catch(Throwable e2){ + log.severe("failed on thread v2 : ${thread.getId()} ${thread.getName()}", e2) + } + } + } +} diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/FrameLocationInfo.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/FrameLocationInfo.groovy index dbb4d23e..9235a4b6 100644 --- a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/FrameLocationInfo.groovy +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/FrameLocationInfo.groovy @@ -1,18 +1,15 @@ package net.sf.jremoterun.utilities.nonjdk.idwutils -import groovy.transform.CompileStatic; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import groovy.transform.CompileStatic -import java.awt.*; -import java.io.Serializable; +import java.awt.* @CompileStatic public class FrameLocationInfo implements Serializable{ -private static final Logger log = LogManager.getLogger(); + public Point location; public Dimension dimension; diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwActions.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwActions.groovy index edf718d3..5ac83568 100644 --- a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwActions.groovy +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwActions.groovy @@ -93,12 +93,12 @@ class IdwActions { if (fw == null && dw.windowParent instanceof FloatingWindow) { fw = dw.windowParent as FloatingWindow } - log.info "${dw.windowParent.class.name}" + //log.info "${dw.windowParent.class.name}" // log.info "${dw.windowParent.windowParent.class.name}" if (fw == null) { log.info "not fw" - if (dw.maximizable) { - log.info "${dw.maximized}" + if (dw.isMaximizable()) { + log.info "isMaximized = ${dw.isMaximized()}" if (dw.maximized) { dw.restore() } else { diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwFrameCreator.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwFrameCreator.groovy new file mode 100644 index 00000000..b125afe9 --- /dev/null +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwFrameCreator.groovy @@ -0,0 +1,66 @@ +package net.sf.jremoterun.utilities.nonjdk.idwutils + +import groovy.transform.CompileStatic +import net.infonode.docking.DockingWindow +import net.infonode.docking.RootWindow +import net.infonode.properties.propertymap.JrrIdwPropertyMapManager; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.idwutils.IdwUtilsStarter +import net.sf.jremoterun.utilities.nonjdk.swing.JPanelBorderLayout +import net.sf.jremoterun.utilities.nonjdk.swing.SimpleFrameCreator + +import javax.imageio.ImageIO +import javax.swing.JFrame +import javax.swing.JPanel +import java.awt.BorderLayout +import java.awt.Container +import java.awt.image.BufferedImage; +import java.util.logging.Logger; + +@CompileStatic +class IdwFrameCreator { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + JFrame frame; + JPanel rootPanel = new JPanelBorderLayout() + + IdwFrameCreator(String frameName,DockingWindow dockingWindow){ + JrrIdwPropertyMapManager.setManager() + RootWindow window = IdwUtilsStarter.createRootWindow() + window.setWindow(dockingWindow) + frame = new JFrame(frameName); + Container contentPane = frame.getContentPane() + contentPane.add(rootPanel, BorderLayout.CENTER); + rootPanel.add(window,BorderLayout.CENTER); + } + + + void setIcon(File f){ + SimpleFrameCreator.setIcon(frame,f); + + } + + void setIcon(InputStream iconRes){ + SimpleFrameCreator.setIcon(frame,iconRes); + + } + + + void setAlwaysOnTopFalse(){ + frame.setAlwaysOnTop(false); + } + + void setExitOnClose(){ + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + } + + void setMaximazedState(){ + frame.setExtendedState(JFrame.MAXIMIZED_BOTH); } + + void setDefaultLocationAndSize(){ + frame.setSize(1201, 284); + frame.setLocation(706, -8); + } + + +} diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtils.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtils.groovy index 16cb25da..714eef51 100644 --- a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtils.groovy +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtils.groovy @@ -102,6 +102,9 @@ class IdwUtils { return getDockerWindowWithPopmenu(popupMenu); } Container parent = component.getParent(); + if(parent==null){ + throw new Exception("No parent for ${component.getClass()} ${component}") + } if (parent instanceof DockingWindow) { DockingWindow new_name = (DockingWindow) parent; return new_name; diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtils2.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtils2.groovy index 69faa5e0..94699c94 100644 --- a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtils2.groovy +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtils2.groovy @@ -3,8 +3,7 @@ package net.sf.jremoterun.utilities.nonjdk.idwutils import groovy.transform.CompileStatic import net.infonode.docking.FloatingWindow import net.sf.jremoterun.utilities.JrrClassUtils -import org.apache.logging.log4j.LogManager -import org.apache.logging.log4j.Logger + import javax.swing.JButton import javax.swing.JPanel @@ -17,10 +16,12 @@ import java.awt.Insets import java.awt.Rectangle import java.awt.Toolkit import java.awt.Window +import java.util.logging.Logger @CompileStatic public class IdwUtils2 { - private static final Logger log = LogManager.getLogger(); + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static Window getRooWindow(Component component) { @@ -35,7 +36,7 @@ public class IdwUtils2 { try { Window window = (Window) JrrClassUtils.getFieldValue(fw, "dialog"); Rectangle screenWorkingArea = getScreenWorkingArea(window); - log.info(screenWorkingArea); + log.info(''+screenWorkingArea); window.setLocation(screenWorkingArea.@x, screenWorkingArea.@y); window.setSize(screenWorkingArea.@width, screenWorkingArea.@height); return true; diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtilsStarter.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtilsStarter.groovy index fb92b330..3381d8c0 100644 --- a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtilsStarter.groovy +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwUtilsStarter.groovy @@ -2,6 +2,7 @@ package net.sf.jremoterun.utilities.nonjdk.idwutils import groovy.transform.CompileStatic import net.infonode.docking.RootWindow +import net.infonode.docking.properties.RootWindowProperties import net.infonode.docking.util.DockingUtil import net.infonode.docking.util.ViewMap import net.sf.jremoterun.utilities.JrrClassUtils @@ -18,6 +19,7 @@ class IdwUtilsStarter { public static RootWindow rootWindow public static IdwPopupMenuFactory idwPopupMenuFactory private static CreationInfo creationStack + public static RootWindowProperties idwProperties = new RootWindowProperties(); public static RootWindow createRootWindow() { if (creationStack != null) { @@ -31,8 +33,13 @@ class IdwUtilsStarter { rootWindow.setPopupMenuFactory(idwPopupMenuFactory) IdwUtils.addMaxButton(rootWindow) // SwitchWindows.register() + rootWindow.getRootWindowProperties().addSuperObject(idwProperties) return rootWindow } + static void useFrames(boolean useFrames){ + IdwUtilsStarter.idwProperties.getFloatingWindowProperties().setUseFrame(useFrames) + } + } diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwWindowFinder.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwWindowFinder.groovy index b841d93f..cca64853 100644 --- a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwWindowFinder.groovy +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/IdwWindowFinder.groovy @@ -71,6 +71,7 @@ class IdwWindowFinder implements KeyEventDispatcher { case KeyEvent.VK_DOWN: treeSwing.requestFocus() treeSwing.requestFocusInWindow() + break; case KeyEvent.VK_ENTER: List windows = findMatchedWindows(); if (windows.size() == 1) { @@ -173,7 +174,7 @@ class IdwWindowFinder implements KeyEventDispatcher { DefaultTreeModel model = treeSwing.getModel() as DefaultTreeModel; DefaultMutableTreeNode root = model.root as DefaultMutableTreeNode; - List childs = new ArrayList(root.children().toList()) + List childs = new ArrayList((List)root.children().toList()) childs.each { root.remove(it as DefaultMutableTreeNode) // model.removeNodeFromParent(it); diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/MyDockingWindowTitleProvider.java b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/MyDockingWindowTitleProvider.groovy similarity index 82% rename from src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/MyDockingWindowTitleProvider.java rename to src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/MyDockingWindowTitleProvider.groovy index 3355674b..cce751f9 100644 --- a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/MyDockingWindowTitleProvider.java +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/MyDockingWindowTitleProvider.groovy @@ -1,9 +1,11 @@ -package net.sf.jremoterun.utilities.nonjdk.idwutils; +package net.sf.jremoterun.utilities.nonjdk.idwutils +import groovy.transform.CompileStatic; import net.infonode.docking.DockingWindow; import net.infonode.docking.title.DockingWindowTitleProvider; import org.apache.log4j.Logger; +@CompileStatic public class MyDockingWindowTitleProvider implements DockingWindowTitleProvider { private static final Logger logger = Logger .getLogger(MyDockingWindowTitleProvider.class); diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/QrCoderPaneCreator.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/QrCoderPaneCreator.groovy new file mode 100644 index 00000000..639ca207 --- /dev/null +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/QrCoderPaneCreator.groovy @@ -0,0 +1,54 @@ +package net.sf.jremoterun.utilities.nonjdk.idwutils + +import groovy.transform.CompileStatic +import net.infonode.docking.SplitWindow; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.swing.QrCodeCreator + +import javax.swing.SwingUtilities +import javax.swing.event.DocumentEvent +import javax.swing.event.DocumentListener; +import java.util.logging.Logger; + +@CompileStatic +class QrCoderPaneCreator { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public TextAreaAndView areaAndView = new TextAreaAndView('Text') + public QrCodeCreator qrCodeCreator = new QrCodeCreator() + public ViewAndPanel imageView = new ViewAndPanel('Code', qrCodeCreator); + + public SplitWindow splitWindow = new SplitWindow(true, areaAndView.view, imageView.view) + + QrCoderPaneCreator() { + addListener1() + IdwUtils.setTitle(splitWindow,'QR code') + } + + void addListener1() { + areaAndView.textArea.getDocument().addDocumentListener(new DocumentListener() { + @Override + void insertUpdate(DocumentEvent e) { + updateText() + } + + @Override + void removeUpdate(DocumentEvent e) { + updateText() + } + + @Override + void changedUpdate(DocumentEvent e) { + updateText() + } + + }) + } + + + void updateText() { + SwingUtilities.invokeLater { + qrCodeCreator.generateQrCode(areaAndView.textArea.getText()) + } + } + +} diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/Shortcuts.java b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/Shortcuts.groovy similarity index 52% rename from src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/Shortcuts.java rename to src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/Shortcuts.groovy index bca75202..98291f6b 100644 --- a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/Shortcuts.java +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/Shortcuts.groovy @@ -1,7 +1,10 @@ -package net.sf.jremoterun.utilities.nonjdk.idwutils; +package net.sf.jremoterun.utilities.nonjdk.idwutils + +import groovy.transform.CompileStatic; import javax.swing.*; +@CompileStatic public interface Shortcuts { String getDisplayName(); @@ -9,5 +12,4 @@ public interface Shortcuts { KeyStroke getKeyStroke(); - // test2 } diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/TextAreaAndView.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/TextAreaAndView.groovy index c2c39d31..b67c24d4 100644 --- a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/TextAreaAndView.groovy +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/TextAreaAndView.groovy @@ -3,9 +3,12 @@ package net.sf.jremoterun.utilities.nonjdk.idwutils import groovy.transform.CompileStatic import net.infonode.docking.View import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.swing.JPanelBorderLayout import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea import org.fife.ui.rtextarea.RTextScrollPane +import javax.swing.JPanel +import java.awt.BorderLayout import java.util.logging.Logger @CompileStatic @@ -14,13 +17,16 @@ class TextAreaAndView { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - RSyntaxTextArea textArea = new RSyntaxTextArea() + RSyntaxTextArea textArea = new RSyntaxTextArea(); - RTextScrollPane scrollPane = new RTextScrollPane(textArea, false) + public JPanel panel = new JPanelBorderLayout() - View view + RTextScrollPane scrollPane = new RTextScrollPane(textArea, false); + + View view; TextAreaAndView(String title) { - view = new View(title, null, scrollPane); + panel.add(scrollPane, BorderLayout.CENTER) + view = new View(title, null, panel); } } diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTable.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTable.groovy new file mode 100644 index 00000000..c887459e --- /dev/null +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTable.groovy @@ -0,0 +1,128 @@ +package net.sf.jremoterun.utilities.nonjdk.idwutils.alerttable + +import groovy.transform.CompileStatic +import net.infonode.docking.SplitWindow +import net.infonode.docking.View +import net.sf.jremoterun.JrrUtils +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.OsInegrationClientI +import net.sf.jremoterun.utilities.nonjdk.idwutils.IdwUtils +import net.sf.jremoterun.utilities.nonjdk.idwutils.TextAreaAndView +import net.sf.jremoterun.utilities.nonjdk.problemchecker.JustStackTrace +import net.sf.jremoterun.utilities.nonjdk.swing.JrrSwingUtils + +import javax.swing.* +import javax.swing.table.DefaultTableModel +import java.awt.BorderLayout +import java.awt.event.MouseAdapter +import java.awt.event.MouseEvent +import java.text.SimpleDateFormat +import java.util.logging.Logger + +@CompileStatic +class AlertTable { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public TextAreaAndView detailsView = new TextAreaAndView('Details') + public DefaultTableModel defaultTableModel = new DefaultTableModel() + public JTable tableSummary = new JTable(defaultTableModel) + + public Vector columnNames = new Vector(AlertTableColumns.values().toList().collect { it.name() }) + JScrollPane tableMsgsScrollPane = new JScrollPane(tableSummary) + View tableMsgsView = new View('Messages', null, tableMsgsScrollPane); + + public SplitWindow splitWindow = new SplitWindow(true, tableMsgsView, detailsView.view); + + public SimpleDateFormat sdf = new SimpleDateFormat('dd HH:mm') + public List exceptionList = [] + public int currentRowShowing = -1; + public JButton showExceptionButton = new JButton('Show exception in IDE') + public OsInegrationClientI inegrationClient; + + public static AlertTable defaultAlertTable = new AlertTable(); + public static Runnable afterAlertAdded; + + AlertTable() { + defaultTableModel.setColumnIdentifiers(columnNames); + tableSummary.addMouseListener(new MouseAdapter() { + @Override + void mouseClicked(MouseEvent e) { + try { + showMsg(tableSummary.getSelectedRow()) + } catch (Throwable e2) { + log.info("failed show selected msg", e2) + JrrUtilities.showException("failed show selected msg", e2) + } + } + }); + showExceptionButton.addActionListener { + try { + String ee = exceptionList.get(currentRowShowing) + inegrationClient.showStackTrace(ee) + } catch (Throwable e2) { + log.info("failed show exception", e2) + JrrUtilities.showException("failed show exception", e2) + } + } + detailsView.panel.add(showExceptionButton, BorderLayout.NORTH) + IdwUtils.setTitle(splitWindow, 'Alert table') + detailsView.textArea.setLineWrap(true); + detailsView.textArea.setWrapStyleWord(true); + detailsView.textArea.setEditable(false); + } + + + protected void showMsg(int activeColumn) { + currentRowShowing = activeColumn; + Vector row = defaultTableModel.getDataVector().get(activeColumn) + int i = columnNames.indexOf(AlertTableColumns.message.name()) + String msg = row.get(i); + detailsView.textArea.setText(msg) + } + + static void addAlertS(String msg) { + addAlertS(msg, null) + } + + static void addAlertS(String msg, Throwable e) { + if (e == null) { + e = new JustStackTrace() + } +// log.info(msg, e) + SwingUtilities.invokeLater { + try { + defaultAlertTable.addAlert(msg, e); + SwingUtilities.invokeLater { + try { + defaultAlertTable.splitWindow.makeVisible() + IdwUtils.setVisible(defaultAlertTable.splitWindow); + if (afterAlertAdded != null) { + afterAlertAdded.run() + } + } catch (Throwable e2) { + log.info("failed show selected msg", e2) + JrrUtilities.showException("failed show selected msg", e2) + } + } + } catch (Throwable e2) { + log.info("failed show selected msg", e2) + JrrUtilities.showException("failed show selected msg", e2) + } + } + } + + void addAlert(String msg, Throwable e) { + String excS = JrrUtils.exceptionToString(e) + Vector row = new Vector() + row.add(sdf.format(new Date())); + msg += " \n ${excS}" + row.add(msg); + defaultTableModel.addRow(row) + exceptionList.add(excS) + detailsView.textArea.setText(msg) + currentRowShowing=exceptionList.size()-1 + } + + +} diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTableColumns.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTableColumns.groovy new file mode 100644 index 00000000..a6a1a8db --- /dev/null +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTableColumns.groovy @@ -0,0 +1,13 @@ +package net.sf.jremoterun.utilities.nonjdk.idwutils.alerttable + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +enum AlertTableColumns { + + time, message, + + +} diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTableWrapper.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTableWrapper.groovy new file mode 100644 index 00000000..1f032c53 --- /dev/null +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/idwutils/alerttable/AlertTableWrapper.groovy @@ -0,0 +1,53 @@ +package net.sf.jremoterun.utilities.nonjdk.idwutils.alerttable + +import groovy.transform.CompileStatic +import net.infonode.docking.SplitWindow +import net.infonode.docking.View +import net.sf.jremoterun.JrrUtils +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.OsInegrationClientI +import net.sf.jremoterun.utilities.nonjdk.idwutils.IdwUtils +import net.sf.jremoterun.utilities.nonjdk.idwutils.TextAreaAndView +import net.sf.jremoterun.utilities.nonjdk.problemchecker.JustStackTrace +import org.codehaus.groovy.runtime.MethodClosure + +import javax.swing.* +import javax.swing.table.DefaultTableModel +import java.awt.* +import java.awt.event.MouseAdapter +import java.awt.event.MouseEvent +import java.text.SimpleDateFormat +import java.util.List +import java.util.logging.Logger + +@CompileStatic +class AlertTableWrapper { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + static void addAlertS(String msg) { + addAlertS(msg, null) + } + + static void addAlertS(String msg, Throwable e) { + if (e == null) { + e = new JustStackTrace() + } + log.info(msg, e); + AlertTable.addAlertS(msg,e) + } + + static void wrapTextInAlert(MethodClosure mc){ + try { + mc.call() + }catch(Throwable ee){ + addAlertS("failed invoke ${mc.getMethod()}",ee) + } + + } + + + + +} diff --git a/src-idw/net/sf/jremoterun/utilities/nonjdk/swing/SimpleFrameCreator.groovy b/src-idw/net/sf/jremoterun/utilities/nonjdk/swing/SimpleFrameCreator.groovy index feec79be..ff312a3a 100644 --- a/src-idw/net/sf/jremoterun/utilities/nonjdk/swing/SimpleFrameCreator.groovy +++ b/src-idw/net/sf/jremoterun/utilities/nonjdk/swing/SimpleFrameCreator.groovy @@ -18,6 +18,12 @@ class SimpleFrameCreator { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + static void setIcon(JFrame frame, File f){ + assert f.exists() + InputStream stream = f.newInputStream(); + setIcon(frame,stream) + + } static void setIcon(JFrame frame, InputStream iconRes){ assert iconRes!=null final BufferedImage image = ImageIO.read(iconRes); @@ -32,8 +38,8 @@ class SimpleFrameCreator { RootWindow window = IdwUtilsStarter.createRootWindow() window.setWindow(dockingWindow) JFrame frame = SimpleFrameCreator.createAppFrame(windowName) - frame.getContentPane().add(window) - return frame + frame.getContentPane().add(window); + return frame; } @@ -44,7 +50,7 @@ class SimpleFrameCreator { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setAlwaysOnTop(false); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); +// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); return frame; diff --git a/src-java8/net/sf/jremoterun/utilities/nonjdk/classpath/java8/VmUtilities.groovy b/src-java8/net/sf/jremoterun/utilities/nonjdk/classpath/java8/VmUtilities.groovy new file mode 100644 index 00000000..decae51b --- /dev/null +++ b/src-java8/net/sf/jremoterun/utilities/nonjdk/classpath/java8/VmUtilities.groovy @@ -0,0 +1,22 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.java8; + +import net.sf.jremoterun.utilities.JrrClassUtils +import sun.misc.VM; + +import java.util.logging.Logger; +import groovy.transform.CompileStatic; + + +@CompileStatic +class VmUtilities { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + // not exit for java9+ + static void setAllowLoadArray(){ + JrrClassUtils.setFieldValue(VM,"allowArraySyntax",true); + JrrClassUtils.setFieldValue(VM,"defaultAllowArraySyntax",true); + assert VM.allowArraySyntax(); + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/JdkCoreMethods.groovy b/src-java8/net/sf/jremoterun/utilities/nonjdk/log/java8/JdkCoreMethods.groovy similarity index 85% rename from src/net/sf/jremoterun/utilities/nonjdk/log/JdkCoreMethods.groovy rename to src-java8/net/sf/jremoterun/utilities/nonjdk/log/java8/JdkCoreMethods.groovy index 272cd8d4..1659a772 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/log/JdkCoreMethods.groovy +++ b/src-java8/net/sf/jremoterun/utilities/nonjdk/log/java8/JdkCoreMethods.groovy @@ -1,4 +1,4 @@ -package net.sf.jremoterun.utilities.nonjdk.log; +package net.sf.jremoterun.utilities.nonjdk.log.java8; import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.groovystarter.st.JdkLogFormatter @@ -18,6 +18,7 @@ class JdkCoreMethods { static boolean platformRedirectDone = false static void setDefaultLevel(PlatformLogger.Level level){ + // file not exit in java11 : JrrClassUtils.setFieldValue(PlatformLogger,'DEFAULT_LEVEL',level) } @@ -27,7 +28,8 @@ class JdkCoreMethods { log.info "redirect already done" }else { platformRedirectDone = true - PlatformLogger.redirectPlatformLoggers(); + // method not exit for java11: + // PlatformLogger.redirectPlatformLoggers(); } } diff --git a/src-jsshext/com/jcraft/jsch/ChannelExecOriginal.groovy b/src-jsshext/com/jcraft/jsch/ChannelExecOriginal.groovy new file mode 100644 index 00000000..3c81ceb2 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/ChannelExecOriginal.groovy @@ -0,0 +1,110 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ChannelExecOriginal extends ChannelExec { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ChannelExecOriginal() { + super() + } + + @Override + void init() throws JSchException { + super.init() + } + + @Override + protected void sendRequests() throws Exception { + super.sendRequests() + } + + @Override + void setRecipient(int foo) { + super.setRecipient(foo) + } + + @Override + int getRecipient() { + return super.getRecipient() + } + + @Override + void getData(Buffer buf) { + super.getData(buf) + } + + @Override + void setLocalWindowSizeMax(int foo) { + super.setLocalWindowSizeMax(foo) + } + + @Override + void setLocalWindowSize(int foo) { + super.setLocalWindowSize(foo) + } + + @Override + void setLocalPacketSize(int foo) { + super.setLocalPacketSize(foo) + } + + @Override + void setRemoteWindowSize(long foo) { + super.setRemoteWindowSize(foo) + } + + @Override + void addRemoteWindowSize(long foo) { + super.addRemoteWindowSize(foo) + } + + @Override + void setRemotePacketSize(int foo) { + super.setRemotePacketSize(foo) + } + + @Override + void write(byte[] foo) throws IOException { + super.write(foo) + } + + @Override + void write(byte[] foo, int s, int l) throws IOException { + super.write(foo, s, l) + } + + @Override + void write_ext(byte[] foo, int s, int l) throws IOException { + super.write_ext(foo, s, l) + } + + @Override + void eof_remote() { + super.eof_remote() + } + + @Override + void eof() { + super.eof() + } + + @Override + void close() { + super.close() + } + + @Override + void setExitStatus(int status) { + super.setExitStatus(status) + } + + @Override + void setSession(Session session) { + super.setSession(session) + } + +} diff --git a/src-jsshext/com/jcraft/jsch/ChannelForwardedTCPIPOriginal.groovy b/src-jsshext/com/jcraft/jsch/ChannelForwardedTCPIPOriginal.groovy new file mode 100644 index 00000000..7917bea0 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/ChannelForwardedTCPIPOriginal.groovy @@ -0,0 +1,15 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ChannelForwardedTCPIPOriginal extends ChannelForwardedTCPIP{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void getData(Buffer buf) { + super.getData(buf) + } +} diff --git a/src-jsshext/com/jcraft/jsch/ChannelSessionOriginal.groovy b/src-jsshext/com/jcraft/jsch/ChannelSessionOriginal.groovy new file mode 100644 index 00000000..86d3e3ab --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/ChannelSessionOriginal.groovy @@ -0,0 +1,13 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ChannelSessionOriginal extends ChannelSession{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public ChannelSessionOriginal() { + } +} diff --git a/src-jsshext/com/jcraft/jsch/ChannelSftpOriginal.groovy b/src-jsshext/com/jcraft/jsch/ChannelSftpOriginal.groovy new file mode 100644 index 00000000..0e15cff9 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/ChannelSftpOriginal.groovy @@ -0,0 +1,105 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ChannelSftpOriginal extends ChannelSftp{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ChannelSftpOriginal() { + + } + + @Override + void init() { + super.init() + } + + @Override + void setRecipient(int foo) { + super.setRecipient(foo) + } + + @Override + int getRecipient() { + return super.getRecipient() + } + + @Override + void getData(Buffer buf) { + super.getData(buf) + } + + @Override + void setLocalWindowSizeMax(int foo) { + super.setLocalWindowSizeMax(foo) + } + + @Override + void setLocalWindowSize(int foo) { + super.setLocalWindowSize(foo) + } + + @Override + void setLocalPacketSize(int foo) { + super.setLocalPacketSize(foo) + } + + @Override + void setRemoteWindowSize(long foo) { + super.setRemoteWindowSize(foo) + } + + @Override + void addRemoteWindowSize(long foo) { + super.addRemoteWindowSize(foo) + } + + @Override + void setRemotePacketSize(int foo) { + super.setRemotePacketSize(foo) + } + + @Override + void write(byte[] foo) throws IOException { + super.write(foo) + } + + @Override + void write(byte[] foo, int s, int l) throws IOException { + super.write(foo, s, l) + } + + @Override + void write_ext(byte[] foo, int s, int l) throws IOException { + super.write_ext(foo, s, l) + } + + @Override + void eof_remote() { + super.eof_remote() + } + + @Override + void eof() { + super.eof() + } + + @Override + void close() { + super.close() + } + + @Override + void setExitStatus(int status) { + super.setExitStatus(status) + } + + @Override + void setSession(Session session) { + super.setSession(session) + } + +} diff --git a/src-jsshext/com/jcraft/jsch/ChannelShellOriginal.groovy b/src-jsshext/com/jcraft/jsch/ChannelShellOriginal.groovy new file mode 100644 index 00000000..935f5e07 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/ChannelShellOriginal.groovy @@ -0,0 +1,103 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ChannelShellOriginal extends ChannelShell{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ChannelShellOriginal() { + super() + } + + @Override + void init() throws JSchException { + super.init() + } + + @Override + protected void sendRequests() throws Exception { + super.sendRequests() + } + + @Override + void setLocalWindowSizeMax(int foo) { + super.setLocalWindowSizeMax(foo) + } + + @Override + void setLocalWindowSize(int foo) { + super.setLocalWindowSize(foo) + } + + @Override + void setLocalPacketSize(int foo) { + super.setLocalPacketSize(foo) + } + + @Override + void setRemoteWindowSize(long foo) { + super.setRemoteWindowSize(foo) + } + + @Override + void addRemoteWindowSize(long foo) { + super.addRemoteWindowSize(foo) + } + + @Override + void setRemotePacketSize(int foo) { + super.setRemotePacketSize(foo) + } + + @Override + void write(byte[] foo) throws IOException { + super.write(foo) + } + + @Override + void write(byte[] foo, int s, int l) throws IOException { + super.write(foo, s, l) + } + + @Override + void write_ext(byte[] foo, int s, int l) throws IOException { + super.write_ext(foo, s, l) + } + + @Override + void eof_remote() { + super.eof_remote() + } + + @Override + void eof() { + super.eof() + } + + @Override + void close() { + super.close() + } + + @Override + void setSession(Session session) { + super.setSession(session) + } + + + @Override + void setExitStatus(int status) { + super.setExitStatus(status) + } + + int getConnectTimeout2(){ + return super.connectTimeout; + } + + Thread getThread2(){ + return super.thread; + } +} diff --git a/src-jsshext/com/jcraft/jsch/ChannelX11Original.groovy b/src-jsshext/com/jcraft/jsch/ChannelX11Original.groovy new file mode 100644 index 00000000..54d511f2 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/ChannelX11Original.groovy @@ -0,0 +1,13 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ChannelX11Original extends ChannelX11{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ChannelX11Original() { + } +} diff --git a/src-jsshext/com/jcraft/jsch/HostCheckResultEnum.groovy b/src-jsshext/com/jcraft/jsch/HostCheckResultEnum.groovy new file mode 100644 index 00000000..ccb86389 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/HostCheckResultEnum.groovy @@ -0,0 +1,21 @@ +package com.jcraft.jsch; + +import groovy.transform.CompileStatic; + +@CompileStatic +public enum HostCheckResultEnum { + + OK(KnownHosts.OK), + CHANGED(KnownHosts.CHANGED), + NOT_INCLUDED(KnownHosts.NOT_INCLUDED), + ; + + public int status; + + HostCheckResultEnum(int status1) { + status = status1; + } + + public static Map statusMap = values().collectEntries{[it.status,it]} + +} diff --git a/src-jsshext/com/jcraft/jsch/JrrJschSessionOriginal.groovy b/src-jsshext/com/jcraft/jsch/JrrJschSessionOriginal.groovy new file mode 100644 index 00000000..9457a573 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/JrrJschSessionOriginal.groovy @@ -0,0 +1,60 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class JrrJschSessionOriginal extends Session{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public JrrJschSessionOriginal(JSch jsch, String username, String host, int port) throws JSchException { + super(jsch, username, host, port) + } + + @Override + void write(Packet packet, Channel c, int length) throws Exception { + super.write(packet, c, length) + } + + @Override + void addChannel(Channel channel) { + super.addChannel(channel) + } + + @Override + void setUserName(String username) { + super.setUserName(username) + } + + @Override + IdentityRepository getIdentityRepository() { + return super.getIdentityRepository() + } + + + int getAuth_failuresC(){ + return auth_failures; + } + + void setAuth_failuresC(int auth_failuresC){ + this.auth_failures = auth_failuresC; + } + + + int getMax_auth_triesC(){ + return max_auth_tries; + } + + void setMax_auth_triesC(int max_auth_triesC){ + this.max_auth_tries = max_auth_triesC; + } + + + + + + + +} diff --git a/src-jsshext/com/jcraft/jsch/JrrJschStaticUtils.java b/src-jsshext/com/jcraft/jsch/JrrJschStaticUtils.java new file mode 100644 index 00000000..8d08ff40 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/JrrJschStaticUtils.java @@ -0,0 +1,18 @@ +package com.jcraft.jsch; + +public class JrrJschStaticUtils { + + public static boolean isChannelSession(Channel channel) { + boolean b = channel instanceof ChannelSession; + return b; + } + + public static void callChannelInit(Channel channel) throws JSchException { + channel.init(); + } + + public static void setJschIo(Channel channel, IO io) { + channel.io = io; + } + +} diff --git a/src-jsshext/com/jcraft/jsch/JrrKnowHostOriginal.groovy b/src-jsshext/com/jcraft/jsch/JrrKnowHostOriginal.groovy new file mode 100644 index 00000000..223089a5 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/JrrKnowHostOriginal.groovy @@ -0,0 +1,40 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class JrrKnowHostOriginal extends KnownHosts{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + JrrKnowHostOriginal(JSch jsch) { + super(jsch) + } + + @Override + void setKnownHosts(InputStream input) throws JSchException { + super.setKnownHosts(input) + } + + @Override + HostKey createHashedHostKey(String host, byte[] key) throws JSchException { + return super.createHashedHostKey(host, key) + } + + @Override + void setKnownHosts(String filename) throws JSchException { + super.setKnownHosts(filename) + } + + @Override + String getKnownHostsFile() { + return super.getKnownHostsFile() + } + + @Override + void dump(OutputStream out) throws IOException { + super.dump(out) + } + +} diff --git a/src-jsshext/com/jcraft/jsch/JrrSchSessionLog.groovy b/src-jsshext/com/jcraft/jsch/JrrSchSessionLog.groovy new file mode 100644 index 00000000..f331f199 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/JrrSchSessionLog.groovy @@ -0,0 +1,21 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class JrrSchSessionLog { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static volatile boolean doLogging = true; + + + void logMsg(String msg) { + if (doLogging) { + log.info(msg); + } + } + + +} diff --git a/src-jsshext/com/jcraft/jsch/JschIOOriginal.groovy b/src-jsshext/com/jcraft/jsch/JschIOOriginal.groovy new file mode 100644 index 00000000..164ff15c --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/JschIOOriginal.groovy @@ -0,0 +1,70 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class JschIOOriginal extends IO{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void setOutputStream(OutputStream out) { + super.setOutputStream(out) + } + + @Override + void setOutputStream(OutputStream out, boolean dontclose) { + super.setOutputStream(out, dontclose) + } + + @Override + void setExtOutputStream(OutputStream out) { + super.setExtOutputStream(out) + } + + @Override + void setExtOutputStream(OutputStream out, boolean dontclose) { + super.setExtOutputStream(out, dontclose) + } + + @Override + void setInputStream(InputStream inputStream) { + super.setInputStream(inputStream) + } + + @Override + void setInputStream(InputStream inputStream, boolean dontclose) { + super.setInputStream(inputStream, dontclose) + } + + @Override + void put(byte[] array, int begin, int length) throws IOException { + super.put(array, begin, length) + } + + @Override + void put_ext(byte[] array, int begin, int length) throws IOException { + super.put_ext(array, begin, length) + } + + @Override + int getByte() throws IOException { + return super.getByte() + } + + @Override + void getByte(byte[] array) throws IOException { + super.getByte(array) + } + + @Override + void getByte(byte[] array, int begin, int length) throws IOException { + super.getByte(array, begin, length) + } + + @Override + void out_close() { + super.out_close() + } +} diff --git a/src-jsshext/com/jcraft/jsch/SshCmds.groovy b/src-jsshext/com/jcraft/jsch/SshCmds.groovy new file mode 100644 index 00000000..00b5ebad --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/SshCmds.groovy @@ -0,0 +1,28 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; + + +@CompileStatic +enum SshCmds { + + SSH_MSG_SERVICE_REQUEST( 5), + SSH_MSG_SERVICE_ACCEPT( 6), +// SSH_MSG_SERVICE_REQUEST( Session.SSH_MSG_SERVICE_REQUEST), +// SSH_MSG_SERVICE_ACCEPT( Session.SSH_MSG_SERVICE_ACCEPT), + SSH_MSG_USERAUTH_REQUEST( UserAuth.SSH_MSG_USERAUTH_REQUEST), + SSH_MSG_USERAUTH_FAILURE( UserAuth.SSH_MSG_USERAUTH_FAILURE), + SSH_MSG_USERAUTH_SUCCESS( UserAuth.SSH_MSG_USERAUTH_SUCCESS), + SSH_MSG_USERAUTH_BANNER( UserAuth.SSH_MSG_USERAUTH_BANNER), + SSH_MSG_USERAUTH_INFO_REQUEST( UserAuth.SSH_MSG_USERAUTH_INFO_REQUEST), + SSH_MSG_USERAUTH_INFO_RESPONSE( UserAuth.SSH_MSG_USERAUTH_INFO_RESPONSE), + SSH_MSG_USERAUTH_PK_OK( UserAuth.SSH_MSG_USERAUTH_PK_OK), + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ( 60), + ; + + public int cmdId; + + SshCmds(int cmdId) { + this.cmdId = cmdId + } +} \ No newline at end of file diff --git a/src-jsshext/com/jcraft/jsch/UserAuthGSSAPIWithMICOriginal.groovy b/src-jsshext/com/jcraft/jsch/UserAuthGSSAPIWithMICOriginal.groovy new file mode 100644 index 00000000..ea095a3b --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/UserAuthGSSAPIWithMICOriginal.groovy @@ -0,0 +1,16 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class UserAuthGSSAPIWithMICOriginal extends UserAuthGSSAPIWithMIC{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + @Override + boolean start(Session session) throws Exception { + return super.start(session) + } + + +} diff --git a/src-jsshext/com/jcraft/jsch/UserAuthKeyboardInteractiveOriginal.groovy b/src-jsshext/com/jcraft/jsch/UserAuthKeyboardInteractiveOriginal.groovy new file mode 100644 index 00000000..c9c37b48 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/UserAuthKeyboardInteractiveOriginal.groovy @@ -0,0 +1,16 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class UserAuthKeyboardInteractiveOriginal extends UserAuthKeyboardInteractive{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + @Override + boolean start(Session session) throws Exception { + return super.start(session) + } + + +} diff --git a/src-jsshext/com/jcraft/jsch/UserAuthLoggingInterface.groovy b/src-jsshext/com/jcraft/jsch/UserAuthLoggingInterface.groovy new file mode 100644 index 00000000..62849dd9 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/UserAuthLoggingInterface.groovy @@ -0,0 +1,21 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +interface UserAuthLoggingInterface { + + boolean canContinue(Session session); + + void logError(String msg); + int getPassphraseCount() ; + + void onReply(int command) ; + + void sendingCommand(SshCmds cmd); + + + +} diff --git a/src-jsshext/com/jcraft/jsch/UserAuthNoneOriginal.groovy b/src-jsshext/com/jcraft/jsch/UserAuthNoneOriginal.groovy new file mode 100644 index 00000000..6f341673 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/UserAuthNoneOriginal.groovy @@ -0,0 +1,16 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class UserAuthNoneOriginal extends UserAuthNone{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + boolean start(Session session) throws Exception { + return super.start(session) + } + +} diff --git a/src-jsshext/com/jcraft/jsch/UserAuthNoneWithLogging.java b/src-jsshext/com/jcraft/jsch/UserAuthNoneWithLogging.java new file mode 100644 index 00000000..62020370 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/UserAuthNoneWithLogging.java @@ -0,0 +1,164 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package com.jcraft.jsch; + +public class UserAuthNoneWithLogging extends UserAuthNone { + // public static final int SSH_MSG_SERVICE_ACCEPT= 6; + private String methods=null; + public Session session; + public JrrSchSessionLog schSessionLog = new JrrSchSessionLog(); + + protected boolean canContinue(Session session) { + return session.auth_failures >= session.max_auth_tries; + } + + protected void logError(String msg) { + schSessionLog.logMsg(msg); + } + + + protected void onReply(int command) { + if(command == SshCmds.SSH_MSG_USERAUTH_SUCCESS.cmdId){ + schSessionLog.logMsg("got reply : ok"); + }else { + schSessionLog.logMsg("got reply : " + command); + } + } + + + protected void sendingCommand(SshCmds cmd){ + schSessionLog.logMsg("sending command : "+cmd.name()); + } + + + + public boolean start(Session session) throws Exception{ + this.session = session; + this.userinfo=session.getUserInfo(); + this.packet=session.packet; + this.buf=packet.getBuffer(); + this.username=session.getUserName(); + + + + // send + // byte SSH_MSG_SERVICE_REQUEST(5) + // string service name "ssh-userauth" + packet.reset(); + buf.putByte((byte)SshCmds.SSH_MSG_SERVICE_REQUEST.cmdId); + buf.putString(Util.str2byte("ssh-userauth")); + sendingCommand(SshCmds.SSH_MSG_SERVICE_REQUEST); + session.write(packet); + + if(JSch.getLogger().isEnabled(Logger.INFO)){ + JSch.getLogger().log(Logger.INFO, + "SSH_MSG_SERVICE_REQUEST sent"); + } + + // receive + // byte SSH_MSG_SERVICE_ACCEPT(6) + // string service name + buf=session.read(buf); + int command=buf.getCommand(); + onReply(command); + boolean result=(command==SshCmds.SSH_MSG_SERVICE_ACCEPT.cmdId); + + if(JSch.getLogger().isEnabled(Logger.INFO)){ + JSch.getLogger().log(Logger.INFO, + "SSH_MSG_SERVICE_ACCEPT received"); + } + if(!result) + return false; + + byte[] _username=null; + _username=Util.str2byte(username); + + // send + // byte SSH_MSG_USERAUTH_REQUEST(50) + // string user name + // string service name ("ssh-connection") + // string "none" + packet.reset(); + buf.putByte((byte)SshCmds.SSH_MSG_USERAUTH_REQUEST.cmdId); + buf.putString(_username); + buf.putString(Util.str2byte("ssh-connection")); + buf.putString(Util.str2byte("none")); + sendingCommand(SshCmds.SSH_MSG_USERAUTH_REQUEST); + session.write(packet); + + loop: + while(true){ + buf=session.read(buf); + command=buf.getCommand()&0xff; + onReply(command); + if(command==SshCmds.SSH_MSG_USERAUTH_SUCCESS.cmdId){ + return true; + } + if(command==SshCmds.SSH_MSG_USERAUTH_BANNER.cmdId){ + buf.getInt(); buf.getByte(); buf.getByte(); + byte[] _message=buf.getString(); + byte[] lang=buf.getString(); + String message=Util.byte2str(_message); + if(userinfo!=null){ + try{ + userinfo.showMessage(message); + } + catch(RuntimeException ee){ + } + } + continue loop; + } + if(command==SshCmds.SSH_MSG_USERAUTH_FAILURE.cmdId){ + buf.getInt(); buf.getByte(); buf.getByte(); + byte[] foo=buf.getString(); + int partial_success=buf.getByte(); + methods=Util.byte2str(foo); +//System.err.println("UserAuthNONE: "+methods+ +// " partial_success:"+(partial_success!=0)); +// if(partial_success!=0){ +// throw new JSchPartialAuthException(new String(foo)); +// } + + break; + } + else{ +// System.err.println("USERAUTH fail ("+command+")"); + throw new JSchException("USERAUTH fail ("+command+")"); + } + } + //throw new JSchException("USERAUTH fail"); + return false; + } + + @Override + public String getMethods(){ + return methods; + } +} diff --git a/src-jsshext/com/jcraft/jsch/UserAuthPasswordOriginal.groovy b/src-jsshext/com/jcraft/jsch/UserAuthPasswordOriginal.groovy new file mode 100644 index 00000000..8b2ccc79 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/UserAuthPasswordOriginal.groovy @@ -0,0 +1,16 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class UserAuthPasswordOriginal extends UserAuthPassword{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + boolean start(Session session) throws Exception { + return super.start(session) + } + +} diff --git a/src-jsshext/com/jcraft/jsch/UserAuthPasswordWithLogging.java b/src-jsshext/com/jcraft/jsch/UserAuthPasswordWithLogging.java new file mode 100644 index 00000000..22039540 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/UserAuthPasswordWithLogging.java @@ -0,0 +1,229 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package com.jcraft.jsch; + +public class UserAuthPasswordWithLogging extends UserAuth { + public static final int SSH_MSG_USERAUTH_PASSWD_CHANGEREQ = 60; + public Session session; + public JrrSchSessionLog schSessionLog = new JrrSchSessionLog(); + + protected boolean canContinue(Session session) { + return session.auth_failures >= session.max_auth_tries; + } + + protected void logError(String msg) { + schSessionLog.logMsg(msg); + } + + + protected void onReply(int command) { + if(command == SshCmds.SSH_MSG_USERAUTH_SUCCESS.cmdId){ + schSessionLog.logMsg("got reply : ok"); + }else { + schSessionLog.logMsg("got reply : " + command); + } + } + + + protected void sendingCommand(SshCmds cmd){ + schSessionLog.logMsg("sending command : "+cmd.name()); + } + + + public boolean start(Session session) throws Exception { + this.session = session; + super.start(session); + + byte[] password = session.password; + String dest = username + "@" + session.host; + if (session.port != 22) { + dest += (":" + session.port); + } + + try { + + while (true) { + + if (canContinue(session)) { + logError("max retry reached"); + return false; + } + + if (password == null) { + if (userinfo == null) { + //throw new JSchException("USERAUTH fail"); + logError("user info is null"); + return false; + } + if (!userinfo.promptPassword("Password for " + dest)) { + throw new JSchAuthCancelException("password"); + //break; + } + + String _password = userinfo.getPassword(); + if (_password == null) { + throw new JSchAuthCancelException("password"); + //break; + } + password = Util.str2byte(_password); + } + + byte[] _username = null; + _username = Util.str2byte(username); + + // send + // byte SSH_MSG_USERAUTH_REQUEST(50) + // string user name + // string service name ("ssh-connection") + // string "password" + // boolen FALSE + // string plaintext password (ISO-10646 UTF-8) + packet.reset(); + buf.putByte((byte) SshCmds.SSH_MSG_USERAUTH_REQUEST.cmdId); + buf.putString(_username); + buf.putString(Util.str2byte("ssh-connection")); + buf.putString(Util.str2byte("password")); + buf.putByte((byte) 0); + buf.putString(password); + sendingCommand(SshCmds.SSH_MSG_USERAUTH_REQUEST); + session.write(packet); + + loop: while (true) { + buf = session.read(buf); + int command = buf.getCommand() & 0xff; + onReply(command); + if (command == SshCmds.SSH_MSG_USERAUTH_SUCCESS.cmdId) { + return true; + } + if (command == SshCmds.SSH_MSG_USERAUTH_BANNER.cmdId) { + buf.getInt(); + buf.getByte(); + buf.getByte(); + byte[] _message = buf.getString(); + byte[] lang = buf.getString(); + String message = Util.byte2str(_message); + if (userinfo != null) { + userinfo.showMessage(message); + } + continue loop; + } + if (command == SshCmds.SSH_MSG_USERAUTH_PASSWD_CHANGEREQ.cmdId) { + buf.getInt(); + buf.getByte(); + buf.getByte(); + byte[] instruction = buf.getString(); + byte[] tag = buf.getString(); + if (userinfo == null || + !(userinfo instanceof UIKeyboardInteractive)) { + if (userinfo != null) { + userinfo.showMessage("Password must be changed."); + } + logError("Password must be changed."); + return false; + } + + UIKeyboardInteractive kbi = (UIKeyboardInteractive) userinfo; + String[] response; + String name = "Password Change Required"; + String[] prompt = {"New Password: "}; + boolean[] echo = {false}; + response = kbi.promptKeyboardInteractive(dest, + name, + Util.byte2str(instruction), + prompt, + echo); + if (response == null) { + throw new JSchAuthCancelException("password"); + } + + byte[] newpassword = Util.str2byte(response[0]); + + // send + // byte SSH_MSG_USERAUTH_REQUEST(50) + // string user name + // string service name ("ssh-connection") + // string "password" + // boolen TRUE + // string plaintext old password (ISO-10646 UTF-8) + // string plaintext new password (ISO-10646 UTF-8) + packet.reset(); + buf.putByte((byte) SshCmds.SSH_MSG_USERAUTH_REQUEST.cmdId); + buf.putString(_username); + buf.putString(Util.str2byte("ssh-connection")); + buf.putString(Util.str2byte("password")); + buf.putByte((byte) 1); + buf.putString(password); + buf.putString(newpassword); + Util.bzero(newpassword); + response = null; + sendingCommand(SshCmds.SSH_MSG_USERAUTH_REQUEST); + session.write(packet); + continue loop; + } + if (command == SshCmds.SSH_MSG_USERAUTH_FAILURE.cmdId) { + buf.getInt(); + buf.getByte(); + buf.getByte(); + byte[] foo = buf.getString(); + int partial_success = buf.getByte(); + //System.err.println(new String(foo)+ + // " partial_success:"+(partial_success!=0)); + if (partial_success != 0) { + throw new JSchPartialAuthException(Util.byte2str(foo)); + } + session.auth_failures++; + break; + } else { + //System.err.println("USERAUTH fail ("+buf.getCommand()+")"); +// throw new JSchException("USERAUTH fail ("+buf.getCommand()+")"); + logError("unknown command returned : " + command); + return false; + } + } + + if (password != null) { + Util.bzero(password); + password = null; + } + + } + + } finally { + if (password != null) { + Util.bzero(password); + password = null; + } + } + + //throw new JSchException("USERAUTH fail"); + //return false; + } + +} diff --git a/src-jsshext/com/jcraft/jsch/UserAuthPublicKeyOriginal.groovy b/src-jsshext/com/jcraft/jsch/UserAuthPublicKeyOriginal.groovy new file mode 100644 index 00000000..de9e6f49 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/UserAuthPublicKeyOriginal.groovy @@ -0,0 +1,15 @@ +package com.jcraft.jsch + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class UserAuthPublicKeyOriginal extends UserAuthPublicKey { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + boolean start(Session session) throws Exception { + return super.start(session) + } +} diff --git a/src-jsshext/com/jcraft/jsch/UserAuthPublicKeyWithLogging.java b/src-jsshext/com/jcraft/jsch/UserAuthPublicKeyWithLogging.java new file mode 100644 index 00000000..5571dd61 --- /dev/null +++ b/src-jsshext/com/jcraft/jsch/UserAuthPublicKeyWithLogging.java @@ -0,0 +1,269 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package com.jcraft.jsch; + +import java.util.Vector; + +public class UserAuthPublicKeyWithLogging extends UserAuth { + + public Session session; + + public JrrSchSessionLog schSessionLog = new JrrSchSessionLog(); + + protected boolean canContinue(Session session) { + return session.auth_failures >= session.max_auth_tries; + } + + protected int getPassphraseCount() { + return 5; + } + + + protected void logError(String msg) { + schSessionLog.logMsg(msg); + } + + + protected void onReply(int command) { + if(command == SshCmds.SSH_MSG_USERAUTH_SUCCESS.cmdId){ + schSessionLog.logMsg("got reply : ok"); + }else { + schSessionLog.logMsg("got reply : " + command); + } + } + + protected void sendingCommand(SshCmds cmd){ + schSessionLog.logMsg("sending command : "+cmd.name()); + } + + + public boolean start(Session session) throws Exception{ + this.session = session; + super.start(session); + + Vector identities=session.getIdentityRepository().getIdentities(); + + byte[] passphrase=null; + byte[] _username=null; + + int command; + + synchronized(identities){ + if(identities.size()<=0){ + return false; + } + + _username=Util.str2byte(username); + + for(int i=0; i>>24); + tmp[1]=(byte)(sidlen>>>16); + tmp[2]=(byte)(sidlen>>>8); + tmp[3]=(byte)(sidlen); + System.arraycopy(sid, 0, tmp, 4, sidlen); + System.arraycopy(buf.buffer, 5, tmp, 4+sidlen, buf.index-5); + byte[] signature=identity.getSignature(tmp); + if(signature==null){ // for example, too long key length. + break; + } + sendingCommand(SshCmds.SSH_MSG_USERAUTH_REQUEST); + buf.putString(signature); + session.write(packet); + + loop2: + while(true){ + buf=session.read(buf); + command=buf.getCommand()&0xff; + onReply(command); + if(command==SshCmds.SSH_MSG_USERAUTH_SUCCESS.cmdId){ + return true; + } + else if(command==SshCmds.SSH_MSG_USERAUTH_BANNER.cmdId){ + buf.getInt(); buf.getByte(); buf.getByte(); + byte[] _message=buf.getString(); + byte[] lang=buf.getString(); + String message=Util.byte2str(_message); + if(userinfo!=null){ + userinfo.showMessage(message); + } + continue loop2; + } + else if(command==SshCmds.SSH_MSG_USERAUTH_FAILURE.cmdId){ + buf.getInt(); buf.getByte(); buf.getByte(); + byte[] foo=buf.getString(); + int partial_success=buf.getByte(); + //System.err.println(new String(foo)+ + // " partial_success:"+(partial_success!=0)); + if(partial_success!=0){ + throw new JSchPartialAuthException(Util.byte2str(foo)); + } + session.auth_failures++; + break; + } + //System.err.println("USERAUTH fail ("+command+")"); + //throw new JSchException("USERAUTH fail ("+command+")"); + break; + } + } + } + return false; + } +} diff --git a/src-logger-ext-methods/net/sf/jremoterun/utilities/nonjdk/log/JdkLoggerExtentionClass.java b/src-logger-ext-methods/net/sf/jremoterun/utilities/nonjdk/log/JdkLoggerExtentionClass.java index 33ef81ea..98b65363 100644 --- a/src-logger-ext-methods/net/sf/jremoterun/utilities/nonjdk/log/JdkLoggerExtentionClass.java +++ b/src-logger-ext-methods/net/sf/jremoterun/utilities/nonjdk/log/JdkLoggerExtentionClass.java @@ -10,40 +10,50 @@ public class JdkLoggerExtentionClass { public static void info(Logger logger, Object msg, Throwable exception) { - loge(logger, Level.INFO, msg.toString(), exception); + loge(logger, Level.INFO, msg, exception); } public static void fine(Logger logger, Object msg, Throwable exception) { - loge(logger, Level.FINE, msg.toString(), exception); + loge(logger, Level.FINE, msg, exception); } public static void warn(Logger logger, Object msg, Throwable exception) { - loge(logger, Level.WARNING, msg.toString(), exception); + loge(logger, Level.WARNING, msg, exception); } public static void severe(Logger logger, Object msg, Throwable exception) { - loge(logger, Level.SEVERE, msg.toString(), exception); + loge(logger, Level.SEVERE, msg, exception); + } + + + public static void error(Logger logger, Object msg, Throwable exception) { + loge(logger, Level.SEVERE, msg, exception); } public static void loge(Logger logger, Level level, Object msg, Throwable exception) { if (logger.isLoggable(level)) { - logger.log(level, msg == null ? null : msg.toString(), exception); + logger.log(level, convertObjectToString(msg), exception); + } + } + + private static String convertObjectToString(Object obj) { + if (obj == null) { + return null; } + return obj.toString(); } public static void log2(Logger logger, Level level, Object msg) { if (logger.isLoggable(level)) { - logger.log(level, msg == null ? null : msg.toString()); + logger.log(level, convertObjectToString(msg)); } } - - public static void info2(Logger logger, Object msg) { log2(logger, Level.INFO, msg); } @@ -64,4 +74,25 @@ public static void error(Logger logger, Object msg) { } + // sometimes exception can't be found, hope this would help + public static void error3(Logger logger, Object msg, Throwable exception) { + loge(logger, Level.SEVERE, msg, exception); + } + + + public static void warn3(Logger logger, Object msg, Throwable exception) { + loge(logger, Level.WARNING, msg, exception); + } + + public static void info3(Logger logger, Object msg, Throwable exception) { + loge(logger, Level.INFO, msg, exception); + } + + public static void debug3(Logger logger, Object msg,Throwable exception) { + loge(logger, Level.FINE, msg, exception); + } + + + + } diff --git a/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/BasicCredentialsProviderMavenJrr.groovy b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/BasicCredentialsProviderMavenJrr.groovy new file mode 100644 index 00000000..9f33e5df --- /dev/null +++ b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/BasicCredentialsProviderMavenJrr.groovy @@ -0,0 +1,49 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.http + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthScope +import org.apache.maven.wagon.providers.http.httpclient.auth.Credentials +import org.apache.maven.wagon.providers.http.httpclient.impl.client.* + +import java.util.logging.Logger + +@CompileStatic +class BasicCredentialsProviderMavenJrr extends BasicCredentialsProvider{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public JrrMavenHttpUtils jrrHttpUtils; + + BasicCredentialsProviderMavenJrr(JrrMavenHttpUtils mavenHttpUtils) { + this.jrrHttpUtils = mavenHttpUtils + } + + @Override + void setCredentials(AuthScope authscope, Credentials credentials) { + if(jrrHttpUtils.doLogging) { + log.info "${authscope} ${credentials}" + } + super.setCredentials(authscope, credentials) + } + + @Override + Credentials getCredentials(AuthScope authscope) { + Credentials credentials = super.getCredentials(authscope) + if(jrrHttpUtils.doLogging) { + log.info "${authscope} ${credentials}" + } + return credentials; + } + + @Override + void clear() { + if(jrrHttpUtils.doLogging) { + log.info "clear" + } + super.clear() + } +// void setCredentials(AuthScope authscope, Credentials credentials); +// +// Credentials getCredentials(AuthScope authscope); +// void clear(); + +} diff --git a/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/JrrMavenDownloadHttpHandler.java b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/JrrMavenDownloadHttpHandler.java new file mode 100644 index 00000000..5265aec3 --- /dev/null +++ b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/JrrMavenDownloadHttpHandler.java @@ -0,0 +1,55 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.http; + +import groovy.transform.CompileStatic; + +import net.sf.jremoterun.utilities.JrrClassUtils; +import org.apache.maven.wagon.providers.http.HttpWagon; +import org.apache.maven.wagon.providers.http.httpclient.HttpException; +import org.apache.maven.wagon.providers.http.httpclient.StatusLine; +import org.apache.maven.wagon.providers.http.httpclient.client.methods.CloseableHttpResponse; +import org.apache.maven.wagon.providers.http.httpclient.client.methods.HttpUriRequest; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + + +// Replace in META-INF\plexus\components.xml from org.apache.maven.wagon.providers.http.HttpWagon +// to this class + +@CompileStatic +public class JrrMavenDownloadHttpHandler extends HttpWagon { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public static int cnt1=12; + public static List fineHttpStatusCodes = new ArrayList<>(); + + static { + fineHttpStatusCodes.add(200); + } + + + @Override + protected CloseableHttpResponse execute(HttpUriRequest httpMethod) throws HttpException, IOException { + try { + CloseableHttpResponse response = super.execute(httpMethod); + onResult(httpMethod,response); + return response; + } catch (HttpException|IOException e) { + log.log(Level.WARNING, httpMethod.getMethod() + " " + httpMethod.getURI() + " failed : ", e); + throw e; + } + } + + void onResult(HttpUriRequest httpMethod,CloseableHttpResponse response){ + StatusLine statusLine = response.getStatusLine(); + if(fineHttpStatusCodes.contains(statusLine.getStatusCode())){ + + }else { + log.info(httpMethod.getMethod() + " " + httpMethod.getURI() + " strange : " + statusLine); + } + } +} diff --git a/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/JrrMavenHttpUtils.groovy b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/JrrMavenHttpUtils.groovy new file mode 100644 index 00000000..36edb7e6 --- /dev/null +++ b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/JrrMavenHttpUtils.groovy @@ -0,0 +1,96 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.http + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import org.apache.maven.wagon.providers.http.httpclient.HttpHost +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthSchemeProvider +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthScope +import org.apache.maven.wagon.providers.http.httpclient.auth.Credentials +import org.apache.maven.wagon.providers.http.httpclient.auth.NTCredentials +import org.apache.maven.wagon.providers.http.httpclient.auth.UsernamePasswordCredentials +import org.apache.maven.wagon.providers.http.httpclient.client.AuthenticationStrategy +import org.apache.maven.wagon.providers.http.httpclient.client.config.AuthSchemes +import org.apache.maven.wagon.providers.http.httpclient.config.Registry +import org.apache.maven.wagon.providers.http.httpclient.config.RegistryBuilder +import org.apache.maven.wagon.providers.http.httpclient.impl.auth.NTLMSchemeFactory +import org.apache.maven.wagon.providers.http.httpclient.impl.client.* +import org.apache.maven.wagon.providers.http.httpclient.impl.conn.SystemDefaultRoutePlanner + +import java.util.logging.Logger + +/** + * @see net.sf.jremoterun.utilities.nonjdk.net.JrrHttpUtils + */ +@CompileStatic +public class JrrMavenHttpUtils { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public ClRef clRef = new ClRef('org.apache.maven.wagon.providers.http.wagon.shared.AbstractHttpClientWagon') + + public HttpClientBuilder httpClientBuilder = HttpClients.custom() + public CloseableHttpClient httpClient1; + public AuthSchemeProvider ntlmSchemeFactory = new NTLMSchemeFactoryMavenJrr(this) + public AuthenticationStrategy proxyAuthenticationStrategy = new ProxyAuthenticationStrategyMavenJrr(this); + public BasicCredentialsProvider credentialsProvider1 = new BasicCredentialsProviderMavenJrr(this); + public Credentials credentials; + public String proxyHost + public String proxyip + public int proxyPort + public boolean doLogging = true + + + void createClient() { + httpClient1 = httpClientBuilder.build(); + } + + void setNTCredentials(String username,String password,String domain){ + credentials = new NTCredentials(username,password,null,domain) + } + + @Deprecated + void setCred(NTCredentials credentials, String proxyHost, int proxyPort) { + this.credentials = credentials; + this.proxyHost = proxyHost; + this.proxyPort = proxyPort; + setCred2() + } + + void setCred2() { + credentialsProvider1.setCredentials(new AuthScope(proxyHost, proxyPort), credentials); + InetAddress name = InetAddress.getByName(proxyHost) + proxyip = name.getHostAddress() + if (proxyip != proxyHost) { + credentialsProvider1.setCredentials(new AuthScope(proxyip, proxyPort), credentials); + } + httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider1) + httpClientBuilder.setProxyAuthenticationStrategy(proxyAuthenticationStrategy) + Registry authSchemeProviderRegistry = RegistryBuilder. create().register(AuthSchemes.NTLM, ntlmSchemeFactory).build(); + httpClientBuilder.setDefaultAuthSchemeRegistry(authSchemeProviderRegistry) + setRouterPlanner() + } + + @Deprecated + void addProxyNtlmAuth3(NTCredentials credentials, String proxyHost, int proxyPort) { + setCred(credentials, proxyHost, proxyPort) + httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider1) + httpClientBuilder.setProxyAuthenticationStrategy(proxyAuthenticationStrategy) + Registry authSchemeProviderRegistry = RegistryBuilder. create().register(AuthSchemes.NTLM, ntlmSchemeFactory).build(); + httpClientBuilder.setDefaultAuthSchemeRegistry(authSchemeProviderRegistry) + setRouterPlanner() + } + + void setRouterPlanner() { + SystemDefaultRoutePlanner routePlanner = new SystemDefaultRoutePlanner(ProxySelector.getDefault()) + httpClientBuilder.setRoutePlanner(routePlanner) + } + + + void setRef() { + createClient() + JrrClassUtils.setFieldValue(clRef, 'httpClient', httpClient1); + } + + +} diff --git a/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/NTLMSchemeFactoryMavenJrr.groovy b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/NTLMSchemeFactoryMavenJrr.groovy new file mode 100644 index 00000000..aa0949bd --- /dev/null +++ b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/NTLMSchemeFactoryMavenJrr.groovy @@ -0,0 +1,47 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.http + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.maven.wagon.providers.http.httpclient.HttpHost +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthScheme +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthSchemeProvider +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthScope +import org.apache.maven.wagon.providers.http.httpclient.auth.NTCredentials +import org.apache.maven.wagon.providers.http.httpclient.auth.UsernamePasswordCredentials +import org.apache.maven.wagon.providers.http.httpclient.client.AuthenticationStrategy +import org.apache.maven.wagon.providers.http.httpclient.client.config.AuthSchemes +import org.apache.maven.wagon.providers.http.httpclient.config.Registry +import org.apache.maven.wagon.providers.http.httpclient.config.RegistryBuilder +import org.apache.maven.wagon.providers.http.httpclient.impl.auth.NTLMSchemeFactory +import org.apache.maven.wagon.providers.http.httpclient.impl.client.* +import org.apache.maven.wagon.providers.http.httpclient.impl.conn.SystemDefaultRoutePlanner +import org.apache.maven.wagon.providers.http.httpclient.params.HttpParams +import org.apache.maven.wagon.providers.http.httpclient.protocol.HttpContext + +import java.util.logging.Logger + +@CompileStatic +class NTLMSchemeFactoryMavenJrr extends NTLMSchemeFactory{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public JrrMavenHttpUtils jrrHttpUtils; + public volatile NTLMSchemeMavenJrr lastNTLMSchemeJrr; + + NTLMSchemeFactoryMavenJrr(JrrMavenHttpUtils jrrHttpUtils) { + this.jrrHttpUtils = jrrHttpUtils + } + + @Override + AuthScheme newInstance(HttpParams params) { + NTLMSchemeMavenJrr ntlmJrr = new NTLMSchemeMavenJrr(jrrHttpUtils) + lastNTLMSchemeJrr = ntlmJrr + return ntlmJrr + } + + @Override + AuthScheme create(HttpContext context) { + NTLMSchemeMavenJrr ntlmJrr = new NTLMSchemeMavenJrr(jrrHttpUtils) + lastNTLMSchemeJrr = ntlmJrr + return ntlmJrr + } +} diff --git a/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/NTLMSchemeMavenJrr.groovy b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/NTLMSchemeMavenJrr.groovy new file mode 100644 index 00000000..1ccdd710 --- /dev/null +++ b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/NTLMSchemeMavenJrr.groovy @@ -0,0 +1,63 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.http + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.nonjdk.net.JrrHttpUtils +import org.apache.maven.wagon.providers.http.httpclient.Header +import org.apache.maven.wagon.providers.http.httpclient.HttpHost +import org.apache.maven.wagon.providers.http.httpclient.HttpRequest +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthSchemeProvider +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthScope +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthenticationException +import org.apache.maven.wagon.providers.http.httpclient.auth.Credentials +import org.apache.maven.wagon.providers.http.httpclient.auth.NTCredentials +import org.apache.maven.wagon.providers.http.httpclient.auth.UsernamePasswordCredentials +import org.apache.maven.wagon.providers.http.httpclient.client.AuthenticationStrategy +import org.apache.maven.wagon.providers.http.httpclient.client.config.AuthSchemes +import org.apache.maven.wagon.providers.http.httpclient.config.Registry +import org.apache.maven.wagon.providers.http.httpclient.config.RegistryBuilder +import org.apache.maven.wagon.providers.http.httpclient.impl.auth.NTLMEngine +import org.apache.maven.wagon.providers.http.httpclient.impl.auth.NTLMScheme +import org.apache.maven.wagon.providers.http.httpclient.impl.auth.NTLMSchemeFactory +import org.apache.maven.wagon.providers.http.httpclient.impl.client.* +import org.apache.maven.wagon.providers.http.httpclient.impl.conn.SystemDefaultRoutePlanner + +import java.util.logging.Logger + +@CompileStatic +class NTLMSchemeMavenJrr extends NTLMScheme{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static ClRef clRefEngineImpl = new ClRef('org.apache.maven.wagon.providers.http.httpclient.impl.auth.NTLMEngineImpl') + + public JrrMavenHttpUtils jrrHttpUtils; + + NTLMSchemeMavenJrr(JrrMavenHttpUtils jrrHttpUtils) { + this.jrrHttpUtils = jrrHttpUtils + } + + NTLMSchemeMavenJrr(NTLMEngine engine, JrrMavenHttpUtils jrrHttpUtils) { + super(engine) + this.jrrHttpUtils = jrrHttpUtils + } + + @Override + Header authenticate(Credentials credentials, HttpRequest request) throws AuthenticationException { + if(jrrHttpUtils.doLogging) { + log.info "proxy auth state = ${getState1()}" + } + return super.authenticate(credentials, request) + } + + public Object getState1(){ + return JrrClassUtils.getFieldValue(this,'state') + } + + + + static NTLMEngine createNTLMEngineImpl(){ + clRefEngineImpl.newInstance3() as NTLMEngine + } + +} diff --git a/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/ProxyAuthenticationStrategyMavenJrr.groovy b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/ProxyAuthenticationStrategyMavenJrr.groovy new file mode 100644 index 00000000..04f79d97 --- /dev/null +++ b/src-maven-http/net/sf/jremoterun/utilities/nonjdk/maven/http/ProxyAuthenticationStrategyMavenJrr.groovy @@ -0,0 +1,92 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.http + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.maven.wagon.providers.http.httpclient.Header +import org.apache.maven.wagon.providers.http.httpclient.HttpHost +import org.apache.maven.wagon.providers.http.httpclient.HttpResponse +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthOption +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthScheme +import org.apache.maven.wagon.providers.http.httpclient.auth.AuthScope +import org.apache.maven.wagon.providers.http.httpclient.auth.Credentials +import org.apache.maven.wagon.providers.http.httpclient.auth.MalformedChallengeException +import org.apache.maven.wagon.providers.http.httpclient.auth.NTCredentials +import org.apache.maven.wagon.providers.http.httpclient.client.CredentialsProvider +import org.apache.maven.wagon.providers.http.httpclient.client.protocol.HttpClientContext +import org.apache.maven.wagon.providers.http.httpclient.impl.client.* +import org.apache.maven.wagon.providers.http.httpclient.protocol.HttpContext + +import java.util.logging.Logger + +@CompileStatic +class ProxyAuthenticationStrategyMavenJrr extends ProxyAuthenticationStrategy{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public JrrMavenHttpUtils jrrHttpUtils; + + + ProxyAuthenticationStrategyMavenJrr(JrrMavenHttpUtils jrrHttpUtils) { + this.jrrHttpUtils = jrrHttpUtils + } + + @Override + boolean isAuthenticationRequested(HttpHost authhost, HttpResponse response, HttpContext context) { + return super.isAuthenticationRequested(authhost, response, context) + } + + @Override + Map getChallenges(HttpHost authhost, HttpResponse response, HttpContext context) throws MalformedChallengeException { + Map challenges = super.getChallenges(authhost, response, context) + if(jrrHttpUtils. doLogging) { + log.info "${authhost} ${challenges}" + } + return challenges + } + + @Override + Queue select(Map challenges, HttpHost authhost, HttpResponse response, HttpContext context) throws MalformedChallengeException { + HttpClientContext clientContext = HttpClientContext.adapt(context); + if (jrrHttpUtils.credentials instanceof NTCredentials) { + CredentialsProvider credentialsProvider = clientContext.getCredentialsProvider() + AuthScope authScope = new AuthScope(jrrHttpUtils.proxyHost, jrrHttpUtils.proxyPort) + Credentials credentials = credentialsProvider.getCredentials(authScope); + if(credentials==null){ + if(jrrHttpUtils.doLogging) { + log.info "pushing credentials for ${authScope}" + } + credentialsProvider.setCredentials(authScope,jrrHttpUtils.credentials) + if(jrrHttpUtils.proxyip!=jrrHttpUtils.proxyHost) { + AuthScope authScope2 = new AuthScope(jrrHttpUtils.proxyip, jrrHttpUtils.proxyPort) + if(jrrHttpUtils.doLogging) { + log.info "pushing credentials for ${authScope2}" + } + credentialsProvider.setCredentials(authScope2, jrrHttpUtils.credentials) + } + context = clientContext; + } + } + Queue select = super.select(challenges, authhost, response, context) + if(jrrHttpUtils.doLogging) { + log.info "${challenges} ${select}" + } + return select + } + + + + @Override + void authSucceeded(HttpHost authhost, AuthScheme authScheme, HttpContext context) { + if(jrrHttpUtils.doLogging) { + log.info "good ${authhost}" + } + super.authSucceeded(authhost, authScheme, context) + } + + @Override + void authFailed(HttpHost authhost, AuthScheme authScheme, HttpContext context) { + if(jrrHttpUtils.doLogging) { + log.info "failed ${authhost}" + } + super.authFailed(authhost, authScheme, context) + } +} diff --git a/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/JrrMavenCli.java b/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/JrrMavenCli.java new file mode 100644 index 00000000..fb3db50f --- /dev/null +++ b/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/JrrMavenCli.java @@ -0,0 +1,30 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.launcher; + +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.classpath.JrrGroovyScriptRunner; +import org.apache.maven.cli.CliRequest; +import org.apache.maven.cli.CliRequestPublic; +import org.apache.maven.shared.utils.logging.MessageUtils; +import org.codehaus.plexus.classworlds.ClassWorld; + +import java.io.File; +import java.util.logging.Logger; + +public class JrrMavenCli extends org.apache.maven.cli.MavenCli { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public JrrMavenCli() { + } + + public JrrMavenCli(ClassWorld classWorld) { + super(classWorld); + } + + @Override + public int doMain(CliRequest cliRequest) { + return super.doMain(cliRequest); + } + + +} diff --git a/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/JrrMavenCliWrapper.java b/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/JrrMavenCliWrapper.java new file mode 100644 index 00000000..81d67e44 --- /dev/null +++ b/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/JrrMavenCliWrapper.java @@ -0,0 +1,194 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.launcher; + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.JrrUtils; +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.classpath.AddFilesToUrlClassLoaderGroovy; +import net.sf.jremoterun.utilities.classpath.JrrGroovyScriptRunner; +import net.sf.jremoterun.utilities.groovystarter.JrrStarterConstatnts; +import net.sf.jremoterun.utilities.groovystarter.JrrStarterVariables; +import net.sf.jremoterun.utilities.groovystarter.runners.RunnableFactory; +import net.sf.jremoterun.utilities.groovystarter.st.JrrRunnerPhase2; +import net.sf.jremoterun.utilities.groovystarter.st.SetConsoleOut2; +import net.sf.jremoterun.utilities.nonjdk.RedirectOutStream; +import org.apache.maven.cli.CliRequestPublic; +import org.apache.maven.shared.utils.logging.MessageUtils; +import org.codehaus.plexus.classworlds.ClassWorld; +import org.codehaus.plexus.classworlds.realm.ClassRealm; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.*; +import java.util.logging.Logger; + +// set main is net.sf.jremoterun.utilities.nonjdk.maven.launcher.JrrMavenCliWrapper from plexus.core +// in bin/m2.conf +// and add : load start jars, onejar and ifframework jar . Accept dirs +@CompileStatic +public class JrrMavenCliWrapper { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static int cnt1 = 15; + public static List args1; + public static org.codehaus.plexus.classworlds.realm.ClassRealm classLoaderRealmThis; + public static ClassWorld classWorld1; + public static org.apache.maven.cli.MavenCli cli; + public static CliRequestPublic cliRequestPublic; + public static AddFilesToUrlClassLoaderGroovy adder; + public static List runBefore = new Vector<>(); + public static List runAfter = new Vector<>(); + public static List runAfterUsingFinally = new Vector<>(); + public static Date startDate = new Date(); + public static volatile int result; + public static String coreRealm = "plexus.core"; + public static String mavenRunnerProp = "jrr.maven.runner"; + public static String mavenHomeProp = "maven.home"; + public static String mavenRunnerFileName = "mavenLauncher.groovy"; + public static volatile JrrMavenCliWrapper jrrMavenCliWrapper = new JrrMavenCliWrapper(); + public static volatile Throwable exception; + + +// public static void main(String[] args) { +// log.info("wrong method used !"); +// org.apache.maven.cli.MavenCli.main(args); +// } + + + public static int main(String[] args, ClassWorld classWorld) throws Exception { + cnt1 = 19; + args1 = new ArrayList<>(Arrays.asList(args)); + classWorld1 = classWorld; + classLoaderRealmThis = (ClassRealm) JrrClassUtils.getCurrentClassLoader(); + setAdder2(); + f1(); + return result; + } + + public static File getMavenHome() throws IOException { + String mavenHome = System.getProperty(mavenHomeProp); + if (mavenHome == null) { + throw new IllegalStateException(mavenHomeProp); + } + File mavenHome2 = new File(mavenHome); + if (!mavenHome2.exists()) { + throw new FileNotFoundException(mavenHome); + } + return mavenHome2.getAbsoluteFile().getCanonicalFile(); + } + + public static void redirectMavenLogs(int maxCount) throws Exception { + File mavenHome = getMavenHome(); + File logDir = new File(mavenHome, "logs"); + if (!logDir.exists()) { + log.info("creating dir : " + logDir.getAbsolutePath()); + if (!logDir.mkdir()) { + throw new IOException("Failed create dir : " + logDir.getAbsolutePath()); + } + } + File outFile = new File(logDir, "out.txt"); + RedirectOutStream.setOutStreamWithRotation(outFile, maxCount); + } + + + public static File calcRunnerFile() { + String mavenRunner = System.getProperty(mavenRunnerProp); + if (mavenRunner != null) { + File file = new File(mavenRunner); + if (!file.exists()) { + throw new RuntimeException("file not found : " + file.getAbsolutePath()); + } + return file; + } + File configRaw = new File(JrrStarterVariables.filesDir, mavenRunnerFileName); + if (configRaw.exists()) { + return configRaw; + } else { + log.info(" skip jrr init as file not found : " + configRaw.getAbsolutePath()); + } + return null; + } + + public static void setAdder2() { + adder = new AddFilesToUrlClassLoaderGroovy(findCoreRealm()); + if (JrrStarterVariables.classesDir != null) { + if (JrrStarterVariables.classesDir.exists()) { + adder.add(JrrStarterVariables.classesDir); + } else { + log.info("skip add dir : " + JrrStarterVariables.classesDir); + } + } + } + + public static org.codehaus.plexus.classworlds.realm.ClassRealm findCoreRealm() { + ClassRealm classRealm = classWorld1.getClassRealm(coreRealm); + if (classRealm == null) { + throw new RuntimeException("Realm not found : " + coreRealm); + } + return classRealm; + } + + + public static void f1() throws Exception { + SetConsoleOut2.setConsoleOutIfNotInited(); + File calcRunnerFile = calcRunnerFile(); + if (calcRunnerFile != null) { + RunnableFactory.createRunner(calcRunnerFile).run(); +// new JrrGroovyScriptRunner(JrrClassUtils.getCurrentClassLoader()).loadSettingsNoParam(file); + } + jrrMavenCliWrapper.mainRunner(); + } + + public void mainRunner() throws Exception { + try { + jrrMavenCliWrapper.createCli(); + jrrMavenCliWrapper.jrrSystemInstall(); + jrrMavenCliWrapper.createCliRequest(); + jrrMavenCliWrapper.doRunRunnable(runBefore); + jrrMavenCliWrapper.mainRunnerImpl(); + jrrMavenCliWrapper.doRunRunnable(runAfter); + jrrMavenCliWrapper.jrrSystemUninstall(); + } catch (Throwable e) { + exception = e; + JrrUtils.throwThrowable(e); + } finally { + jrrMavenCliWrapper.doRunRunnable(runAfterUsingFinally); + } + } + + public void doRunRunnable(Runnable r) { + if (r != null) { + r.run(); + } + } + + public void doRunRunnable(List rList) { + for (Runnable r : rList) { + r.run(); + } + } + + public void createCli() { + if (cli == null) { + cli = new JrrMavenCli(); + } + } + + + public void createCliRequest() { + cliRequestPublic = new CliRequestPublic(JrrMavenCliWrapper.args1.toArray(new String[0]), JrrMavenCliWrapper.classWorld1); + } + + public void jrrSystemInstall() { + MessageUtils.systemInstall(); + MessageUtils.registerShutdownHook(); + } + + public void mainRunnerImpl() { + JrrMavenCliWrapper.result = cli.doMain(cliRequestPublic); + } + + public void jrrSystemUninstall() { + MessageUtils.systemUninstall(); + } +} diff --git a/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/utils/JrrClassWorldListener.groovy b/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/utils/JrrClassWorldListener.groovy new file mode 100644 index 00000000..ce389ff5 --- /dev/null +++ b/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/utils/JrrClassWorldListener.groovy @@ -0,0 +1,23 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.launcher.utils + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.codehaus.plexus.classworlds.ClassWorldListener +import org.codehaus.plexus.classworlds.realm.ClassRealm; + +import java.util.logging.Logger; + +@CompileStatic +class JrrClassWorldListener implements ClassWorldListener { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void realmCreated(ClassRealm realm) { + log.info "realm created ${realm.getId()} ${realm.getURLs()}" + } + + @Override + void realmDisposed(ClassRealm realm) { + log.info "realm disposed ${realm.getId()} ${realm.getURLs()}" + } +} diff --git a/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/utils/RealmDumper.groovy b/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/utils/RealmDumper.groovy new file mode 100644 index 00000000..829b18c2 --- /dev/null +++ b/src-maven-launcher/net/sf/jremoterun/utilities/nonjdk/maven/launcher/utils/RealmDumper.groovy @@ -0,0 +1,32 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.launcher.utils + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.maven.http.JrrMavenDownloadHttpHandler +import org.codehaus.plexus.classworlds.ClassWorld +import org.codehaus.plexus.classworlds.realm.ClassRealm; + +import java.util.logging.Logger; + +@CompileStatic +class RealmDumper { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + static void dumpClassloader(org.codehaus.plexus.classworlds.realm.ClassRealm realm) { + URL[] urLs = realm.getURLs(); + log.info("urls : " + Arrays.toString(urLs)); +// Thread.dumpStack(); +// ClassRealm parentRealm = realm.getParentRealm(); + ClassWorld world = realm.getWorld(); + Collection realms = world.getRealms(); + int count=1; + for (ClassRealm realm23 : realms) { + "" + realm23.getId() + " " + realm23 + " " + Arrays.toString(realm23.getURLs()) + log.info("count = ${count} : ${realm23.getId()} ${realm23} ${realm23.getURLs()}"); + count++ + } + } + + +} diff --git a/src-maven-launcher/org/apache/maven/cli/CliRequestPublic.java b/src-maven-launcher/org/apache/maven/cli/CliRequestPublic.java new file mode 100644 index 00000000..1aadaf6f --- /dev/null +++ b/src-maven-launcher/org/apache/maven/cli/CliRequestPublic.java @@ -0,0 +1,60 @@ +package org.apache.maven.cli; + +import org.apache.commons.cli.CommandLine; +import org.apache.maven.execution.MavenExecutionRequest; +import org.codehaus.plexus.classworlds.ClassWorld; + +import java.io.File; +import java.util.Properties; + +public class CliRequestPublic extends org.apache.maven.cli.CliRequest{ + public CliRequestPublic(String[] args, ClassWorld classWorld) { + super(args, classWorld); + } + + + public void setArgs(String[] args) { + this.args = args; + } + + public void setCommandLine(CommandLine commandLine) { + this.commandLine = commandLine; + } + + public void setClassWorld(ClassWorld classWorld) { + this.classWorld = classWorld; + } + + public void setWorkingDirectory(String workingDirectory) { + this.workingDirectory = workingDirectory; + } + + public void setMultiModuleProjectDirectory(File multiModuleProjectDirectory) { + this.multiModuleProjectDirectory = multiModuleProjectDirectory; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + + public void setQuiet(boolean quiet) { + this.quiet = quiet; + } + + public void setShowErrors(boolean showErrors) { + this.showErrors = showErrors; + } + + @Override + public void setUserProperties(Properties userProperties) { + this.userProperties = userProperties; + } + + public void setSystemProperties(Properties systemProperties) { + this.systemProperties = systemProperties; + } + + public void setRequest(MavenExecutionRequest request) { + this.request = request; + } +} diff --git a/src-maven-plugin-ext/net/sf/jremoterun/utilities/nonjdk/maven/pluginext/JrrMavenPluginExt.java b/src-maven-plugin-ext/net/sf/jremoterun/utilities/nonjdk/maven/pluginext/JrrMavenPluginExt.java new file mode 100644 index 00000000..0c26c819 --- /dev/null +++ b/src-maven-plugin-ext/net/sf/jremoterun/utilities/nonjdk/maven/pluginext/JrrMavenPluginExt.java @@ -0,0 +1,37 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.pluginext; + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.classpath.ClRef; +import net.sf.jremoterun.utilities.groovystarter.runners.RunnableFactory; +import net.sf.jremoterun.utilities.groovystarter.runners.RunnableWithParamsFactory; +import net.sf.jremoterun.utilities.javassist.codeinjector.InjectedCode; +import org.apache.maven.plugin.AbstractMojo; + +import java.io.File; +import java.util.logging.Logger; + +@CompileStatic +public class JrrMavenPluginExt extends InjectedCode { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static AbstractMojo abstractMojo; + public static String insidePluginFileName="jrrInsidePluginFileName"; + public static File file; + + @Override + public Object getImpl(Object key) throws Exception { + log.info ("hello world2"); + abstractMojo = (AbstractMojo) key; + + //File f = " somefile\\configs_s\\addMaven.groovy" as File; + if(file==null){ + String propertyValue = System.getProperty(insidePluginFileName); + if(propertyValue==null){ + throw new Exception("Set prop : ${insidePluginFileName}"); + } + file = new File(propertyValue); + } + RunnableFactory.createRunner(file).run(); + return null; + } +} diff --git a/src-maven-plugin-ext/net/sf/jremoterun/utilities/nonjdk/maven/pluginext/NoopMavenModelValidator.java b/src-maven-plugin-ext/net/sf/jremoterun/utilities/nonjdk/maven/pluginext/NoopMavenModelValidator.java new file mode 100644 index 00000000..4ae4ed0a --- /dev/null +++ b/src-maven-plugin-ext/net/sf/jremoterun/utilities/nonjdk/maven/pluginext/NoopMavenModelValidator.java @@ -0,0 +1,19 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.pluginext; + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import org.apache.maven.model.Model; +import org.apache.maven.project.validation.DefaultModelValidator; +import org.apache.maven.project.validation.ModelValidationResult; + +import java.util.logging.Logger; + +@CompileStatic +class NoopMavenModelValidator extends DefaultModelValidator { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + public ModelValidationResult validate(Model model) { + return new ModelValidationResult(); + } +} diff --git a/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/MavenRunner.groovy b/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/MavenRunner.groovy new file mode 100644 index 00000000..b5788cd5 --- /dev/null +++ b/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/MavenRunner.groovy @@ -0,0 +1,124 @@ +package net.sf.jremoterun.utilities.nonjdk.maven + +import groovy.transform.CompileStatic +import net.sf.jremoterun.JrrUtils +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import org.codehaus.plexus.classworlds.launcher.Launcher +import org.codehaus.plexus.classworlds.realm.ClassRealm +import org.codehaus.plexus.classworlds.realm.NoSuchRealmException + +import java.lang.reflect.InvocationTargetException +import java.util.logging.Logger + +@CompileStatic +class MavenRunner extends org.codehaus.plexus.classworlds.launcher.Launcher{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + ClRef mavenCli = new ClRef('org.apache.maven.cli.MavenCli') + + + void run(List args2) { + log.info "running maven ..." + String[] args = args2.toArray(new String[0]); + int code = mainWithExitCodeJrr(args) + log.info "code = ${code}" + } + + @Override + protected void launchEnhanced(String[] args) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchRealmException { + log.info "launching enhanced" +// ClassRealm mainRealm = getMainRealm(); + +// Class mainClass = getMainClass(); +// log.info "${mainClass.getName()}" +// log.info2 JrrUtils.getClassLocation(mainClass) +// log.info "cl ${mainClass.getClassLoader()}" +// log.info "parent cl = ${mainClass.getClassLoader().getParent()}" +// log.info "cl class = ${mainClass.getClassLoader().getClass().getName()}" + super.launchEnhanced(args) + } + + @Override + protected void launchStandard(String[] args) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchRealmException { + log.info "launching standard" + super.launchStandard(args) + } + + int mainWithExitCodeJrr( String[] args ) + throws Exception + { + MavenRunner launcher = this + String classworldsConf = System.getProperty( launcher.CLASSWORLDS_CONF ); + + InputStream is; + + + + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + + launcher.setSystemClassLoader( cl ); + + if ( classworldsConf != null ) + { + is = new FileInputStream( classworldsConf ); + } + else + { + if ( "true".equals( System.getProperty( "classworlds.bootstrapped" ) ) ) + { + is = cl.getResourceAsStream( launcher.UBERJAR_CONF_DIR + launcher.CLASSWORLDS_CONF ); + } + else + { + is = cl.getResourceAsStream( launcher.CLASSWORLDS_CONF ); + } + } + + if ( is == null ) + { + throw new Exception( "classworlds configuration not specified nor found in the classpath" ); + } + + launcher.configure( is ); + + is.close(); + + try + { + launcher.launch( args ); + } + catch ( InvocationTargetException e ) + { + log.info("failed via one launcher",e) + ClassRealm realm = launcher.getWorld().getRealm( launcher.getMainRealmName() ); + + URL[] constituents = realm.getURLs(); + + System.out.println( "---------------------------------------------------" ); + + for ( int i = 0; i < constituents.length; i++ ) + { + System.out.println( "constituent[" + i + "]: " + constituents[i] ); + } + + System.out.println( "---------------------------------------------------" ); + + // Decode ITE (if we can) + Throwable t = e.getTargetException(); + + if ( t instanceof Exception ) + { + throw (Exception) t; + } + if ( t instanceof Error ) + { + throw (Error) t; + } + + // Else just toss the ITE + throw e; + } + + return launcher.getExitCode(); + } +} diff --git a/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/MavenRunnerLauncher.groovy b/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/MavenRunnerLauncher.groovy new file mode 100644 index 00000000..86c38b0e --- /dev/null +++ b/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/MavenRunnerLauncher.groovy @@ -0,0 +1,37 @@ +package net.sf.jremoterun.utilities.nonjdk.maven + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams +import net.sf.jremoterun.utilities.groovystarter.st.GroovyMethodRunnerParams2 +import org.codehaus.plexus.classworlds.launcher.Launcher +import org.codehaus.plexus.classworlds.realm.ClassRealm +import org.codehaus.plexus.classworlds.realm.NoSuchRealmException + +import java.lang.reflect.InvocationTargetException +import java.util.logging.Logger + +@CompileStatic +class MavenRunnerLauncher { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static ClRef mavenRunner = new ClRef('net.sf.jremoterun.utilities.nonjdk.maven.MavenRunner') + + static void runMaven(File mavenBaseDir) { + GroovyMethodRunnerParams.gmrp.addFilesToClassLoader.addAllJarsInDir mavenBaseDir.child('boot/') + File m2Config = mavenBaseDir.child('bin/m2.conf') + assert m2Config.exists() + System.setProperty('classworlds.conf', m2Config.getAbsolutePath()) + System.setProperty('maven.home', mavenBaseDir.getAbsolutePath()) + File jasnsiNative = mavenBaseDir.child('lib/jansi-native/') + assert jasnsiNative.exists() + System.setProperty('library.jansi.path', jasnsiNative.getAbsolutePath()) + File userDir = new File(System.getProperty("user.dir")); + assert userDir.exists() + userDir = userDir.getCanonicalFile().getAbsoluteFile() + System.setProperty('maven.multiModuleProjectDirectory', userDir.getAbsolutePath()) + GroovyMethodRunnerParams2.gmrp2.mainClass = mavenRunner + } + +} diff --git a/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenHttpTransporterFactoryJrr.groovy b/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenHttpTransporterFactoryJrr.groovy new file mode 100644 index 00000000..a8bc96f2 --- /dev/null +++ b/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenHttpTransporterFactoryJrr.groovy @@ -0,0 +1,33 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.mavenupload + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.eclipse.aether.RepositorySystemSession +import org.eclipse.aether.repository.RemoteRepository +import org.eclipse.aether.spi.connector.transport.Transporter +import org.eclipse.aether.spi.connector.transport.TransporterFactory +import org.eclipse.aether.transfer.NoTransporterException +import org.eclipse.aether.transport.http.HttpTransporterFactory +import org.eclipse.aether.transport.http.HttpTransporterJrr; + +import java.util.logging.Logger; + +@CompileStatic +class MavenHttpTransporterFactoryJrr implements TransporterFactory { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public HttpTransporterFactory origin = new HttpTransporterFactory(); + + @Override + Transporter newInstance(RepositorySystemSession session, RemoteRepository repository) throws NoTransporterException { + Map configProperties = session.getConfigProperties() + log.info "config keys = ${configProperties.keySet()}" + Transporter transporter = new HttpTransporterJrr(repository,session) + return transporter + } + + @Override + float getPriority() { + return origin.getPriority() + } +} diff --git a/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenUploader.groovy b/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenUploader.groovy new file mode 100644 index 00000000..6e2e3e57 --- /dev/null +++ b/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenUploader.groovy @@ -0,0 +1,139 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.mavenupload + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.MavenMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.MavenResolverMavenIds +import org.apache.commons.io.FilenameUtils +import org.apache.maven.repository.internal.MavenSettingsJrr +import org.eclipse.aether.metadata.Metadata +import org.eclipse.aether.repository.Authentication +import org.eclipse.aether.util.repository.AuthenticationBuilder + +import java.util.logging.Logger; + +import org.apache.maven.repository.internal.DefaultArtifactDescriptorReader +import org.apache.maven.repository.internal.DefaultVersionRangeResolver +import org.apache.maven.repository.internal.DefaultVersionResolver +import org.apache.maven.repository.internal.SnapshotMetadataGeneratorFactoryJrr +import org.apache.maven.repository.internal.VersionsMetadataGeneratorFactory +import org.eclipse.aether.DefaultRepositorySystemSession +import org.eclipse.aether.RepositorySystem +import org.eclipse.aether.artifact.Artifact +import org.eclipse.aether.artifact.DefaultArtifact +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory +import org.eclipse.aether.deployment.DeployRequest +import org.eclipse.aether.impl.ArtifactDescriptorReader +import org.eclipse.aether.impl.DefaultServiceLocator +import org.eclipse.aether.impl.MetadataGeneratorFactory +import org.eclipse.aether.impl.VersionRangeResolver +import org.eclipse.aether.impl.VersionResolver +import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory +import org.eclipse.aether.repository.LocalRepository +import org.eclipse.aether.repository.LocalRepositoryManager +import org.eclipse.aether.repository.RemoteRepository +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory +import org.eclipse.aether.spi.connector.transport.TransporterFactory + +// https://github.com/sonatype/nexus-book-examples/blob/master/ant-aether/simple-project-staging/build.xml +@CompileStatic +class MavenUploader { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static final String SNAPSHOT = Metadata.Nature.SNAPSHOT.name(); + + + public DefaultServiceLocator dsl = new DefaultServiceLocator(); + public DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(); + public RemoteRepository.Builder repoBuilder; + public DeployRequest request = new DeployRequest(); + public List artifacts = [] + public Boolean snapshotBuild = false + public LocalRepository localRepository; + public SimpleLocalRepositoryManagerFactory simpleLocalRepositoryManagerFactory = new SimpleLocalRepositoryManagerFactory() + public MavenSettingsJrr mavenSettingsJrr = new MavenSettingsJrr(); + + MavenUploader(String url, File localRepo) { + repoBuilder = new RemoteRepository.Builder('jrrrepo', "default", url); + localRepository = new LocalRepository(localRepo); + } + + void init() { + dsl.setErrorHandler(new DefaultServiceLocator.ErrorHandler() { + @Override + void serviceCreationFailed(Class type, Class impl, Throwable exception) { + log.severe("failed create ${type.getName()} with impl = ${impl.getName()} : ${exception}") +// log.log(Level.SEVERE, 'maven uploader failed', exception) + throw exception + } + }) + addService(ArtifactDescriptorReader, DefaultArtifactDescriptorReader); + addService(VersionRangeResolver, DefaultVersionRangeResolver); + addService(VersionResolver, DefaultVersionResolver); + addService(RepositoryConnectorFactory, BasicRepositoryConnectorFactory); + addService(TransporterFactory, MavenHttpTransporterFactoryJrr); + + + addService(MetadataGeneratorFactory, VersionsMetadataGeneratorFactory); + addService(MetadataGeneratorFactory, SnapshotMetadataGeneratorFactoryJrr); + } + + File createPomFileAndAdd(MavenId mavenId) { + String childPath = mavenId.groupId.replace('.', '/') + '/' + mavenId.artifactId + '/' + mavenId.version + '/'+mavenId.artifactId+'-'+mavenId.version+'.pom'; + File basedir = localRepository.getBasedir() + assert basedir.exists() + File pomPath = new File(basedir, childPath) + File parentFile = pomPath.getParentFile() + parentFile.mkdirs() + assert parentFile.exists() + pomPath.text = createPomStr(mavenId); + addArtifact(pomPath, mavenId) + return pomPath; + } + + String createPomStr(MavenId mavenId) { + String pom12 = """ + + 4.0.0 + + ${mavenId.groupId} + ${mavenId.artifactId} + ${mavenId.version} + + +""" + return pom12 + } + + void addArtifact(File file, MavenId mavenId) { + String extension = FilenameUtils.getExtension(file.getName()) + Artifact artifact1 = new DefaultArtifact(mavenId.groupId, mavenId.artifactId, '', extension,mavenId.version,null,file); + artifacts.add(artifact1) + } + + void setAuth(String username,String password){ + Authentication authentication = new AuthenticationBuilder().addUsername(username).addPassword(password).build() + repoBuilder.setAuthentication(authentication) + } + + void deploy() { + session.setConfigProperty(MavenSettingsJrr.mavenSettingsJrrS,mavenSettingsJrr) + LocalRepositoryManager localRepositoryManager = simpleLocalRepositoryManagerFactory.newInstance(session, localRepository); + session.setLocalRepositoryManager(localRepositoryManager) + request.setArtifacts(artifacts); + + RemoteRepository remoteRepository = repoBuilder.build() + request.setRepository(remoteRepository); +// dsl.getService(Deployer).deploy(session, request); + dsl.getService(RepositorySystem).deploy(session, request); + } + + + void addService(Class class1, Class class2) { + dsl.addService(class1, class2) + } +} diff --git a/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenUploaderMavenId.groovy b/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenUploaderMavenId.groovy new file mode 100644 index 00000000..a1e15ee6 --- /dev/null +++ b/src-maven/net/sf/jremoterun/utilities/nonjdk/maven/mavenupload/MavenUploaderMavenId.groovy @@ -0,0 +1,37 @@ +package net.sf.jremoterun.utilities.nonjdk.maven.mavenupload + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.MavenMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.MavenResolverMavenIds; + +import java.util.logging.Logger; + +@CompileStatic +class MavenUploaderMavenId { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static List neededMavenIds = (List)[ + MavenMavenIds. artifact, + MavenMavenIds.builder_support, + MavenMavenIds.model_builder, + MavenMavenIds.model, + MavenMavenIds.repository_metadata, + MavenMavenIds.resolver_provider, + MavenMavenIds.slf4j_provider, + LatestMavenIds.plexus_utils, + MavenResolverMavenIds.api, + MavenResolverMavenIds.connector_basic, + MavenResolverMavenIds.impl, + MavenResolverMavenIds.named_locks, + MavenResolverMavenIds.spi, + MavenResolverMavenIds.transport_http, + MavenResolverMavenIds.util, + + ] + + + +} diff --git a/src-maven/org/apache/maven/repository/internal/MavenSettingsJrr.groovy b/src-maven/org/apache/maven/repository/internal/MavenSettingsJrr.groovy new file mode 100644 index 00000000..3e4b4652 --- /dev/null +++ b/src-maven/org/apache/maven/repository/internal/MavenSettingsJrr.groovy @@ -0,0 +1,11 @@ +package org.apache.maven.repository.internal + +import groovy.transform.CompileStatic; + +@CompileStatic +public class MavenSettingsJrr { + + public static final String mavenSettingsJrrS = 'mavenSettingsJrr'; + + public boolean createSnapShotUpload = true; +} diff --git a/src-maven/org/apache/maven/repository/internal/RemoteSnapshotMetadataGeneratorJrr.java b/src-maven/org/apache/maven/repository/internal/RemoteSnapshotMetadataGeneratorJrr.java new file mode 100644 index 00000000..834fe8ba --- /dev/null +++ b/src-maven/org/apache/maven/repository/internal/RemoteSnapshotMetadataGeneratorJrr.java @@ -0,0 +1,110 @@ +package org.apache.maven.repository.internal; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.deployment.DeployRequest; +import org.eclipse.aether.impl.MetadataGenerator; +import org.eclipse.aether.metadata.Metadata; +import org.eclipse.aether.util.ConfigUtils; + +/** + * @author Benjamin Bentmann + */ +public class RemoteSnapshotMetadataGeneratorJrr + implements MetadataGenerator +{ + + private final Map snapshots; + + private final boolean legacyFormat; + + public RepositorySystemSession session; + + public RemoteSnapshotMetadataGeneratorJrr(RepositorySystemSession session, DeployRequest request ) + { + this.session = session; + legacyFormat = ConfigUtils.getBoolean( session.getConfigProperties(), false, "maven.metadata.legacy" ); + + snapshots = new LinkedHashMap<>(); + + /* + * NOTE: This should be considered a quirk to support interop with Maven's legacy ArtifactDeployer which + * processes one artifact at a time and hence cannot associate the artifacts from the same project to use the + * same timestamp+buildno for the snapshot versions. Allowing the caller to pass in metadata from a previous + * deployment allows to re-establish the association between the artifacts of the same project. + */ + for ( Metadata metadata : request.getMetadata() ) + { + if ( metadata instanceof RemoteSnapshotMetadataJrr) + { + RemoteSnapshotMetadataJrr snapshotMetadata = (RemoteSnapshotMetadataJrr) metadata; + snapshots.put( snapshotMetadata.getKey(), snapshotMetadata ); + } + } + } + + public Collection prepare( Collection artifacts ) + { + for ( Artifact artifact : artifacts ) + { + if ( artifact.isSnapshot() ) + { + Object key = RemoteSnapshotMetadataJrr.getKey( artifact ); + RemoteSnapshotMetadataJrr snapshotMetadata = snapshots.get( key ); + if ( snapshotMetadata == null ) + { + snapshotMetadata = new RemoteSnapshotMetadataJrr( artifact, legacyFormat,session ); + snapshots.put( key, snapshotMetadata ); + } + snapshotMetadata.bind( artifact ); + } + } + + return snapshots.values(); + } + + public Artifact transformArtifact( Artifact artifact ) + { + if ( artifact.isSnapshot() && artifact.getVersion().equals( artifact.getBaseVersion() ) ) + { + Object key = RemoteSnapshotMetadataJrr.getKey( artifact ); + RemoteSnapshotMetadataJrr snapshotMetadata = snapshots.get( key ); + if ( snapshotMetadata != null ) + { + artifact = artifact.setVersion( snapshotMetadata.getExpandedVersion( artifact ) ); + } + } + + return artifact; + } + + public Collection finish( Collection artifacts ) + { + return Collections.emptyList(); + } + +} diff --git a/src-maven/org/apache/maven/repository/internal/RemoteSnapshotMetadataJrr.java b/src-maven/org/apache/maven/repository/internal/RemoteSnapshotMetadataJrr.java new file mode 100644 index 00000000..39824900 --- /dev/null +++ b/src-maven/org/apache/maven/repository/internal/RemoteSnapshotMetadataJrr.java @@ -0,0 +1,174 @@ +package org.apache.maven.repository.internal; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.TimeZone; + +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.artifact.repository.metadata.Snapshot; +import org.apache.maven.artifact.repository.metadata.SnapshotVersion; +import org.apache.maven.artifact.repository.metadata.Versioning; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; + +/** + * @author Benjamin Bentmann + */ +public class RemoteSnapshotMetadataJrr + extends MavenSnapshotMetadata +{ + public static final String DEFAULT_SNAPSHOT_TIMESTAMP_FORMAT = "yyyyMMdd.HHmmss"; + + public static final TimeZone DEFAULT_SNAPSHOT_TIME_ZONE = TimeZone.getTimeZone( "Etc/UTC" ); + + private final Map versions = new LinkedHashMap<>(); + public RepositorySystemSession session; + + public RemoteSnapshotMetadataJrr(Artifact artifact, boolean legacyFormat, RepositorySystemSession session ) + { + super( createRepositoryMetadata( artifact, legacyFormat ), null, legacyFormat ); + this.session = session; + } + + private RemoteSnapshotMetadataJrr(Metadata metadata, File file, boolean legacyFormat, RepositorySystemSession session ) + { + super( metadata, file, legacyFormat ); + this.session = session; + } + + public MavenMetadata setFile( File file ) + { + return new RemoteSnapshotMetadataJrr( metadata, file, legacyFormat ,session); + } + + public String getExpandedVersion( Artifact artifact ) + { + String key = getKey( artifact.getClassifier(), artifact.getExtension() ); + return versions.get( key ).getVersion(); + } + + @Override + protected void merge( Metadata recessive ) + { + Snapshot snapshot = null; + String lastUpdated; + boolean createSnapshots = true; + MavenSettingsJrr objs = (MavenSettingsJrr) session.getConfigProperties().get(MavenSettingsJrr.mavenSettingsJrrS); + if(objs!=null){ + createSnapshots = objs.createSnapShotUpload; + } + + if ( metadata.getVersioning() == null ) + { + DateFormat utcDateFormatter = new SimpleDateFormat(DEFAULT_SNAPSHOT_TIMESTAMP_FORMAT); + if(createSnapshots) { + + utcDateFormatter.setCalendar(new GregorianCalendar()); + utcDateFormatter.setTimeZone(DEFAULT_SNAPSHOT_TIME_ZONE); + + snapshot = new Snapshot(); + snapshot.setBuildNumber(getBuildNumber(recessive) + 1); + snapshot.setTimestamp(utcDateFormatter.format(new Date())); + + Versioning versioning = new Versioning(); + versioning.setSnapshot(snapshot); + versioning.setLastUpdated(snapshot.getTimestamp().replace(".", "")); + lastUpdated = versioning.getLastUpdated(); + + metadata.setVersioning(versioning); + }else{ + lastUpdated = utcDateFormatter.format(new Date()).replace(".", ""); + Versioning versioning = new Versioning(); + versioning.setLastUpdated(lastUpdated); + metadata.setVersioning(versioning); + } + } + else + { + snapshot = metadata.getVersioning().getSnapshot(); + lastUpdated = metadata.getVersioning().getLastUpdated(); + } + + for ( Artifact artifact : artifacts ) + { + String version = artifact.getVersion(); + + if ( version.endsWith( SNAPSHOT ) && createSnapshots ) + { + String qualifier = snapshot.getTimestamp() + '-' + snapshot.getBuildNumber(); + version = version.substring( 0, version.length() - SNAPSHOT.length() ) + qualifier; + } + + SnapshotVersion sv = new SnapshotVersion(); + sv.setClassifier( artifact.getClassifier() ); + sv.setExtension( artifact.getExtension() ); + sv.setVersion( version ); + sv.setUpdated( lastUpdated ); + + versions.put( getKey( sv.getClassifier(), sv.getExtension() ), sv ); + } + + artifacts.clear(); + + Versioning versioning = recessive.getVersioning(); + if ( versioning != null ) + { + for ( SnapshotVersion sv : versioning.getSnapshotVersions() ) + { + String key = getKey( sv.getClassifier(), sv.getExtension() ); + if ( !versions.containsKey( key ) ) + { + versions.put( key, sv ); + } + } + } + + if ( !legacyFormat ) + { + metadata.getVersioning().setSnapshotVersions( new ArrayList<>( versions.values() ) ); + } + } + + private static int getBuildNumber( Metadata metadata ) + { + int number = 0; + + Versioning versioning = metadata.getVersioning(); + if ( versioning != null ) + { + Snapshot snapshot = versioning.getSnapshot(); + if ( snapshot != null && snapshot.getBuildNumber() > 0 ) + { + number = snapshot.getBuildNumber(); + } + } + + return number; + } + +} diff --git a/src-maven/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactoryJrr.java b/src-maven/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactoryJrr.java new file mode 100644 index 00000000..db7403eb --- /dev/null +++ b/src-maven/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactoryJrr.java @@ -0,0 +1,55 @@ +package org.apache.maven.repository.internal; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.deployment.DeployRequest; +import org.eclipse.aether.impl.MetadataGenerator; +import org.eclipse.aether.impl.MetadataGeneratorFactory; +import org.eclipse.aether.installation.InstallRequest; + +/** + * @author Benjamin Bentmann + */ +@Named( "snapshot" ) +@Singleton +public class SnapshotMetadataGeneratorFactoryJrr + implements MetadataGeneratorFactory +{ + + public MetadataGenerator newInstance( RepositorySystemSession session, InstallRequest request ) + { + return new LocalSnapshotMetadataGenerator( session, request ); + } + + public MetadataGenerator newInstance( RepositorySystemSession session, DeployRequest request ) + { + return new RemoteSnapshotMetadataGeneratorJrr( session, request ); + } + + public float getPriority() + { + return 10; + } + +} diff --git a/src-maven/org/eclipse/aether/transport/http/HttpTransporterJrr.java b/src-maven/org/eclipse/aether/transport/http/HttpTransporterJrr.java new file mode 100644 index 00000000..b1ef687b --- /dev/null +++ b/src-maven/org/eclipse/aether/transport/http/HttpTransporterJrr.java @@ -0,0 +1,604 @@ +package org.eclipse.aether.transport.http; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.InterruptedIOException; +import java.io.OutputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpHeaders; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.params.AuthParams; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.HttpClient; +import org.apache.http.client.HttpResponseException; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.methods.HttpOptions; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.utils.DateUtils; +import org.apache.http.client.utils.URIUtils; +import org.apache.http.conn.params.ConnRouteParams; +import org.apache.http.entity.AbstractHttpEntity; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.impl.client.DecompressingHttpClient; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.util.EntityUtils; +import org.eclipse.aether.ConfigurationProperties; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.repository.AuthenticationContext; +import org.eclipse.aether.repository.Proxy; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.spi.connector.transport.AbstractTransporter; +import org.eclipse.aether.spi.connector.transport.GetTask; +import org.eclipse.aether.spi.connector.transport.PeekTask; +import org.eclipse.aether.spi.connector.transport.PutTask; +import org.eclipse.aether.spi.connector.transport.TransportTask; +import org.eclipse.aether.transfer.NoTransporterException; +import org.eclipse.aether.transfer.TransferCancelledException; +import org.eclipse.aether.util.ConfigUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A transporter for HTTP/HTTPS. + * Changes : 1) added method logAction + * 2) changed private -> protected + * 3) remove final from class declaration + */ +public class HttpTransporterJrr + extends AbstractTransporter +{ + + protected static final Pattern CONTENT_RANGE_PATTERN = + Pattern.compile( "\\s*bytes\\s+([0-9]+)\\s*-\\s*([0-9]+)\\s*/.*" ); + + protected static final Logger LOGGER = LoggerFactory.getLogger( HttpTransporter.class ); + + protected final AuthenticationContext repoAuthContext; + + protected final AuthenticationContext proxyAuthContext; + + protected final URI baseUri; + + protected final HttpHost server; + + protected final HttpHost proxy; + + protected final HttpClient client; + + protected final Map headers; + + protected final LocalState state; + + public HttpTransporterJrr( RemoteRepository repository, RepositorySystemSession session ) + throws NoTransporterException + { + if ( !"http".equalsIgnoreCase( repository.getProtocol() ) + && !"https".equalsIgnoreCase( repository.getProtocol() ) ) + { + throw new NoTransporterException( repository ); + } + try + { + baseUri = new URI( repository.getUrl() ).parseServerAuthority(); + if ( baseUri.isOpaque() ) + { + throw new URISyntaxException( repository.getUrl(), "URL must not be opaque" ); + } + server = URIUtils.extractHost( baseUri ); + if ( server == null ) + { + throw new URISyntaxException( repository.getUrl(), "URL lacks host name" ); + } + } + catch ( URISyntaxException e ) + { + throw new NoTransporterException( repository, e.getMessage(), e ); + } + proxy = toHost( repository.getProxy() ); + + repoAuthContext = AuthenticationContext.forRepository( session, repository ); + proxyAuthContext = AuthenticationContext.forProxy( session, repository ); + + state = new LocalState( session, repository, new SslConfig( session, repoAuthContext ) ); + + headers = + ConfigUtils.getMap( session, Collections.emptyMap(), ConfigurationProperties.HTTP_HEADERS + "." + + repository.getId(), ConfigurationProperties.HTTP_HEADERS ); + + DefaultHttpClient client = new DefaultHttpClient( state.getConnectionManager() ); + + configureClient( client.getParams(), session, repository, proxy ); + + client.setCredentialsProvider( toCredentialsProvider( server, repoAuthContext, proxy, proxyAuthContext ) ); + + this.client = new DecompressingHttpClient( client ); + } + + protected static HttpHost toHost( Proxy proxy ) + { + HttpHost host = null; + if ( proxy != null ) + { + host = new HttpHost( proxy.getHost(), proxy.getPort() ); + } + return host; + } + + protected static void configureClient( HttpParams params, RepositorySystemSession session, + RemoteRepository repository, HttpHost proxy ) + { + AuthParams.setCredentialCharset( params, ConfigUtils.getString( session, + ConfigurationProperties.DEFAULT_HTTP_CREDENTIAL_ENCODING, + ConfigurationProperties.HTTP_CREDENTIAL_ENCODING + "." + repository.getId(), + ConfigurationProperties.HTTP_CREDENTIAL_ENCODING ) ); + ConnRouteParams.setDefaultProxy( params, proxy ); + HttpConnectionParams.setConnectionTimeout( params, ConfigUtils.getInteger( session, + ConfigurationProperties.DEFAULT_CONNECT_TIMEOUT, + ConfigurationProperties.CONNECT_TIMEOUT + "." + repository.getId(), + ConfigurationProperties.CONNECT_TIMEOUT ) ); + HttpConnectionParams.setSoTimeout( params, ConfigUtils.getInteger( session, + ConfigurationProperties.DEFAULT_REQUEST_TIMEOUT, + ConfigurationProperties.REQUEST_TIMEOUT + "." + repository.getId(), + ConfigurationProperties.REQUEST_TIMEOUT ) ); + HttpProtocolParams.setUserAgent( params, ConfigUtils.getString( session, + ConfigurationProperties.DEFAULT_USER_AGENT, + ConfigurationProperties.USER_AGENT ) ); + } + + protected static CredentialsProvider toCredentialsProvider( HttpHost server, AuthenticationContext serverAuthCtx, + HttpHost proxy, AuthenticationContext proxyAuthCtx ) + { + CredentialsProvider provider = toCredentialsProvider( server.getHostName(), AuthScope.ANY_PORT, serverAuthCtx ); + if ( proxy != null ) + { + CredentialsProvider p = toCredentialsProvider( proxy.getHostName(), proxy.getPort(), proxyAuthCtx ); + provider = new DemuxCredentialsProvider( provider, p, proxy ); + } + return provider; + } + + protected static CredentialsProvider toCredentialsProvider( String host, int port, AuthenticationContext ctx ) + { + DeferredCredentialsProvider provider = new DeferredCredentialsProvider(); + if ( ctx != null ) + { + AuthScope basicScope = new AuthScope( host, port ); + provider.setCredentials( basicScope, new DeferredCredentialsProvider.BasicFactory( ctx ) ); + + AuthScope ntlmScope = new AuthScope( host, port, AuthScope.ANY_REALM, "ntlm" ); + provider.setCredentials( ntlmScope, new DeferredCredentialsProvider.NtlmFactory( ctx ) ); + } + return provider; + } + + LocalState getState() + { + return state; + } + + protected URI resolve( TransportTask task ) + { + return UriUtils.resolve( baseUri, task.getLocation() ); + } + + public int classify( Throwable error ) + { + if ( error instanceof HttpResponseException + && ( (HttpResponseException) error ).getStatusCode() == HttpStatus.SC_NOT_FOUND ) + { + return ERROR_NOT_FOUND; + } + return ERROR_OTHER; + } + + @Override + protected void implPeek( PeekTask task ) + throws Exception + { + HttpHead request = commonHeaders( new HttpHead( resolve( task ) ) ); + execute( request, null ); + } + + @Override + protected void implGet( GetTask task ) + throws Exception + { + EntityGetter getter = new EntityGetter( task ); + HttpGet request = commonHeaders( new HttpGet( resolve( task ) ) ); + resume( request, task ); + try + { + execute( request, getter ); + } + catch ( HttpResponseException e ) + { + if ( e.getStatusCode() == HttpStatus.SC_PRECONDITION_FAILED && request.containsHeader( HttpHeaders.RANGE ) ) + { + request = commonHeaders( new HttpGet( request.getURI() ) ); + execute( request, getter ); + return; + } + throw e; + } + } + + @Override + protected void implPut( PutTask task ) + throws Exception + { + PutTaskEntity entity = new PutTaskEntity( task ); + HttpPut request = commonHeaders( entity( new HttpPut( resolve( task ) ), entity ) ); + try + { + execute( request, null ); + } + catch ( HttpResponseException e ) + { + if ( e.getStatusCode() == HttpStatus.SC_EXPECTATION_FAILED && request.containsHeader( HttpHeaders.EXPECT ) ) + { + state.setExpectContinue( false ); + request = commonHeaders( entity( new HttpPut( request.getURI() ), entity ) ); + execute( request, null ); + return; + } + throw e; + } + } + + + protected void logAction(HttpUriRequest request, EntityGetter getter){ + LOGGER.info("doing : "+request.getMethod()+" "+request.getURI()); + } + + protected void execute( HttpUriRequest request, EntityGetter getter ) + throws Exception + { + try + { + SharingHttpContext context = new SharingHttpContext( state ); + prepare( request, context ); + logAction(request,getter); + HttpResponse response = client.execute( server, request, context ); + try + { + context.close(); + handleStatus( response ); + if ( getter != null ) + { + getter.handle( response ); + } + } + finally + { + EntityUtils.consumeQuietly( response.getEntity() ); + } + } + catch ( IOException e ) + { + if ( e.getCause() instanceof TransferCancelledException ) + { + throw (Exception) e.getCause(); + } + throw e; + } + } + + protected void prepare( HttpUriRequest request, SharingHttpContext context ) + { + boolean put = HttpPut.METHOD_NAME.equalsIgnoreCase( request.getMethod() ); + if ( state.getWebDav() == null && ( put || isPayloadPresent( request ) ) ) + { + try + { + HttpOptions req = commonHeaders( new HttpOptions( request.getURI() ) ); + HttpResponse response = client.execute( server, req, context ); + state.setWebDav( isWebDav( response ) ); + EntityUtils.consumeQuietly( response.getEntity() ); + } + catch ( IOException e ) + { + LOGGER.debug( "Failed to prepare HTTP context", e ); + } + } + if ( put && Boolean.TRUE.equals( state.getWebDav() ) ) + { + mkdirs( request.getURI(), context ); + } + } + + protected boolean isWebDav( HttpResponse response ) + { + return response.containsHeader( HttpHeaders.DAV ); + } + + @SuppressWarnings( "checkstyle:magicnumber" ) + protected void mkdirs( URI uri, SharingHttpContext context ) + { + List dirs = UriUtils.getDirectories( baseUri, uri ); + int index = 0; + for ( ; index < dirs.size(); index++ ) + { + try + { + HttpResponse response = + client.execute( server, commonHeaders( new HttpMkCol( dirs.get( index ) ) ), context ); + try + { + int status = response.getStatusLine().getStatusCode(); + if ( status < 300 || status == HttpStatus.SC_METHOD_NOT_ALLOWED ) + { + break; + } + else if ( status == HttpStatus.SC_CONFLICT ) + { + continue; + } + handleStatus( response ); + } + finally + { + EntityUtils.consumeQuietly( response.getEntity() ); + } + } + catch ( IOException e ) + { + LOGGER.debug( "Failed to create parent directory {}", dirs.get( index ), e ); + return; + } + } + for ( index--; index >= 0; index-- ) + { + try + { + HttpResponse response = + client.execute( server, commonHeaders( new HttpMkCol( dirs.get( index ) ) ), context ); + try + { + handleStatus( response ); + } + finally + { + EntityUtils.consumeQuietly( response.getEntity() ); + } + } + catch ( IOException e ) + { + LOGGER.debug( "Failed to create parent directory {}", dirs.get( index ), e ); + return; + } + } + } + + protected T entity( T request, HttpEntity entity ) + { + request.setEntity( entity ); + return request; + } + + protected boolean isPayloadPresent( HttpUriRequest request ) + { + if ( request instanceof HttpEntityEnclosingRequest ) + { + HttpEntity entity = ( (HttpEntityEnclosingRequest) request ).getEntity(); + return entity != null && entity.getContentLength() != 0; + } + return false; + } + + protected T commonHeaders( T request ) + { + request.setHeader( HttpHeaders.CACHE_CONTROL, "no-cache, no-store" ); + request.setHeader( HttpHeaders.PRAGMA, "no-cache" ); + + if ( state.isExpectContinue() && isPayloadPresent( request ) ) + { + request.setHeader( HttpHeaders.EXPECT, "100-continue" ); + } + + for ( Map.Entry entry : headers.entrySet() ) + { + if ( !( entry.getKey() instanceof String ) ) + { + continue; + } + if ( entry.getValue() instanceof String ) + { + request.setHeader( entry.getKey().toString(), entry.getValue().toString() ); + } + else + { + request.removeHeaders( entry.getKey().toString() ); + } + } + + if ( !state.isExpectContinue() ) + { + request.removeHeaders( HttpHeaders.EXPECT ); + } + + return request; + } + + @SuppressWarnings( "checkstyle:magicnumber" ) + protected T resume( T request, GetTask task ) + { + long resumeOffset = task.getResumeOffset(); + if ( resumeOffset > 0L && task.getDataFile() != null ) + { + request.setHeader( HttpHeaders.RANGE, "bytes=" + resumeOffset + '-' ); + request.setHeader( HttpHeaders.IF_UNMODIFIED_SINCE, + DateUtils.formatDate( new Date( task.getDataFile().lastModified() - 60L * 1000L ) ) ); + request.setHeader( HttpHeaders.ACCEPT_ENCODING, "identity" ); + } + return request; + } + + @SuppressWarnings( "checkstyle:magicnumber" ) + protected void handleStatus( HttpResponse response ) + throws HttpResponseException + { + int status = response.getStatusLine().getStatusCode(); + if ( status >= 300 ) + { + throw new HttpResponseException( status, response.getStatusLine().getReasonPhrase() + " (" + status + ")" ); + } + } + + @Override + protected void implClose() + { + AuthenticationContext.close( repoAuthContext ); + AuthenticationContext.close( proxyAuthContext ); + state.close(); + } + + protected class EntityGetter + { + + protected final GetTask task; + + EntityGetter( GetTask task ) + { + this.task = task; + } + + public void handle( HttpResponse response ) + throws IOException, TransferCancelledException + { + HttpEntity entity = response.getEntity(); + if ( entity == null ) + { + entity = new ByteArrayEntity( new byte[0] ); + } + + long offset = 0L, length = entity.getContentLength(); + String range = getHeader( response, HttpHeaders.CONTENT_RANGE ); + if ( range != null ) + { + Matcher m = CONTENT_RANGE_PATTERN.matcher( range ); + if ( !m.matches() ) + { + throw new IOException( "Invalid Content-Range header for partial download: " + range ); + } + offset = Long.parseLong( m.group( 1 ) ); + length = Long.parseLong( m.group( 2 ) ) + 1L; + if ( offset < 0L || offset >= length || ( offset > 0L && offset != task.getResumeOffset() ) ) + { + throw new IOException( "Invalid Content-Range header for partial download from offset " + + task.getResumeOffset() + ": " + range ); + } + } + + InputStream is = entity.getContent(); + utilGet( task, is, true, length, offset > 0L ); + extractChecksums( response ); + } + + protected void extractChecksums( HttpResponse response ) + { + // Nexus-style, ETag: "{SHA1{d40d68ba1f88d8e9b0040f175a6ff41928abd5e7}}" + String etag = getHeader( response, HttpHeaders.ETAG ); + if ( etag != null ) + { + int start = etag.indexOf( "SHA1{" ), end = etag.indexOf( "}", start + 5 ); + if ( start >= 0 && end > start ) + { + task.setChecksum( "SHA-1", etag.substring( start + 5, end ) ); + } + } + } + + protected String getHeader( HttpResponse response, String name ) + { + Header header = response.getFirstHeader( name ); + return ( header != null ) ? header.getValue() : null; + } + + } + + protected class PutTaskEntity + extends AbstractHttpEntity + { + + protected final PutTask task; + + PutTaskEntity( PutTask task ) + { + this.task = task; + } + + public boolean isRepeatable() + { + return true; + } + + public boolean isStreaming() + { + return false; + } + + public long getContentLength() + { + return task.getDataLength(); + } + + public InputStream getContent() + throws IOException + { + return task.newInputStream(); + } + + public void writeTo( OutputStream os ) + throws IOException + { + try + { + utilPut( task, os, false ); + } + catch ( TransferCancelledException e ) + { + throw (IOException) new InterruptedIOException().initCause( e ); + } + } + + } + +} diff --git a/src-netbeans/net/sf/jremoterun/utilities/nonjdk/netbeans/heapwalker/OpenInIdeHeap.groovy b/src-netbeans/net/sf/jremoterun/utilities/nonjdk/netbeans/heapwalker/OpenInIdeHeap.groovy new file mode 100644 index 00000000..c2638d4f --- /dev/null +++ b/src-netbeans/net/sf/jremoterun/utilities/nonjdk/netbeans/heapwalker/OpenInIdeHeap.groovy @@ -0,0 +1,142 @@ +package net.sf.jremoterun.utilities.nonjdk.netbeans.heapwalker + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.OsInegrationClientI +import org.netbeans.lib.profiler.ui.components.JExtendedTable +import org.netbeans.lib.profiler.ui.components.JTreeTable +import org.netbeans.modules.profiler.heapwalk.ClassesController +import org.netbeans.modules.profiler.heapwalk.ClassesListController +import org.netbeans.modules.profiler.heapwalk.FieldsBrowserController +import org.netbeans.modules.profiler.heapwalk.HeapFragmentWalker +import org.netbeans.modules.profiler.heapwalk.HeapWalker +import org.netbeans.modules.profiler.heapwalk.InstancesController +import org.netbeans.modules.profiler.heapwalk.ReferencesBrowserController +import org.netbeans.modules.profiler.heapwalk.model.BrowserUtils +import org.netbeans.modules.profiler.heapwalk.model.HeapWalkerNode +import org.netbeans.modules.profiler.heapwalk.ui.ClassesListControllerUI +import org.netbeans.modules.profiler.heapwalk.ui.FieldsBrowserControllerUI +import org.netbeans.modules.profiler.heapwalk.ui.HeapWalkerUI +import org.netbeans.modules.profiler.heapwalk.ui.ReferencesBrowserControllerUI +import org.openide.windows.TopComponent + +import javax.swing.JFrame +import javax.swing.JMenuItem +import javax.swing.JPopupMenu +import javax.swing.tree.TreePath; +import java.util.logging.Logger; + +@CompileStatic +class OpenInIdeHeap { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + HeapWalker heapWalker + OsInegrationClientI inegrationClientI + HeapFragmentWalker mainHeapWalker + InstancesController instancesController + + OpenInIdeHeap(HeapWalker heapWalker, OsInegrationClientI inegrationClientI) { + this.heapWalker = heapWalker + this.inegrationClientI = inegrationClientI + mainHeapWalker = heapWalker.getMainHeapWalker(); + instancesController = mainHeapWalker.getInstancesController() + } + + static HeapWalker createUi(File heapFile) { + HeapWalker heapWalker = new HeapWalker(heapFile); + //HeapWalkerUI heapWalkerUI = heapWalker.getTopComponent() as HeapWalkerUI;// new HeapWalkerUI(heapWalker); + return heapWalker; + } + + void addAll() { + addRefSupport(); + addClassSupport() + addFieldsSupport(); + } + + + void addRefSupport() { + ReferencesBrowserController referencesBrowserController = instancesController.getReferencesBrowserController() + ReferencesBrowserControllerUI referencesBrowserControllerUI = referencesBrowserController.getPanel() as ReferencesBrowserControllerUI + JPopupMenu popupMenuFields = JrrClassUtils.getFieldValue(referencesBrowserControllerUI, 'tablePopup') as JPopupMenu + JMenuItem openClassInIde = new JMenuItem('open field in ide') + JrrClassUtils.setFieldValue(referencesBrowserControllerUI, 'showSourceItem', openClassInIde) + openClassInIde.addActionListener { + JTreeTable fieldsListTable = JrrClassUtils.getFieldValue(referencesBrowserControllerUI, 'fieldsListTable') as JTreeTable + int row = fieldsListTable.getSelectedRow(); + log.info "field row ${row}" + if (row != -1) { + TreePath pathForRow = fieldsListTable.getTree().getPathForRow(row) + Object lastPathComponent = pathForRow.getLastPathComponent() + if (lastPathComponent instanceof HeapWalkerNode) { + HeapWalkerNode heapWalkerNode = (HeapWalkerNode) lastPathComponent; + String fieldName = heapWalkerNode.getName(); + String clasType = traslateClassName(heapWalkerNode.getType()) + log.info "opening c=${clasType} f=${fieldName} .." + inegrationClientI.openField(clasType, fieldName); + } + //HeapWalkerNode node = + + } + } + popupMenuFields.add(openClassInIde) + + } + + void addFieldsSupport() { + FieldsBrowserController fieldsBrowserController = instancesController.getFieldsBrowserController() + FieldsBrowserControllerUI fieldsBrowserControllerUI = fieldsBrowserController.getPanel() as FieldsBrowserControllerUI + JPopupMenu popupMenuFields = JrrClassUtils.getFieldValue(fieldsBrowserControllerUI, 'tablePopup') as JPopupMenu + JMenuItem openClassInIde = new JMenuItem('open field in ide') +// JrrClassUtils.setFieldValue(fieldsBrowserControllerUI, 'showSourceItem', openClassInIde) + openClassInIde.addActionListener { + JTreeTable fieldsListTable = JrrClassUtils.getFieldValue(fieldsBrowserControllerUI, 'fieldsListTable') as JTreeTable + int row = fieldsListTable.getSelectedRow(); + log.info "field row ${row}" + if (row != -1) { + TreePath pathForRow = fieldsListTable.getTree().getPathForRow(row) +// IstyStartupUtils.showObjectInIsty(pathForRow) + Object lastPathComponent = pathForRow.getLastPathComponent() + if (lastPathComponent instanceof HeapWalkerNode) { + HeapWalkerNode heapWalkerNode = (HeapWalkerNode) lastPathComponent; + String fieldName = heapWalkerNode.getName(); + HeapWalkerNode walkerNodeParent = heapWalkerNode.getParent() + String clasType = traslateClassName(walkerNodeParent.getType()) + log.info "opening c=${clasType} f=${fieldName} .." + inegrationClientI.openField(clasType, fieldName); + } + //HeapWalkerNode node = + + } + } + popupMenuFields.add(openClassInIde) + } + + String traslateClassName(String cl) { + return cl.replace('$', '.') + } + + void addClassSupport() { + ClassesController classesController = mainHeapWalker.getClassesController(); + ClassesListController classesListController = classesController.getClassesListController() + ClassesListControllerUI classesListControllerUI = classesListController.getPanel() as ClassesListControllerUI + JPopupMenu popupMenuClasses = JrrClassUtils.getFieldValue(classesListControllerUI, 'tablePopup') as JPopupMenu + JMenuItem openClassInIde = new JMenuItem('open class in ide') + JrrClassUtils.setFieldValue(classesListControllerUI, 'showSourceItem', openClassInIde) + openClassInIde.addActionListener { + JExtendedTable classesListTable = JrrClassUtils.getFieldValue(classesListControllerUI, 'classesListTable') as JExtendedTable + int row = classesListTable.getSelectedRow(); + log.info "row = ${row}" + if (row != -1) { + Object[][] displayCache = JrrClassUtils.getFieldValue(classesListControllerUI, 'displayCache') as Object[][] + String className = traslateClassName(BrowserUtils.getArrayBaseType((String) displayCache[row][0])); + log.info "opening ${className}" + inegrationClientI.openClass(className) + } + + } + popupMenuClasses.add(openClassInIde) + } + + +} diff --git a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/GroovyShellGuiRSyntaxTextArea.groovy b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/GroovyShellGuiRSyntaxTextArea.groovy index 7f0dabb5..86da65b9 100644 --- a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/GroovyShellGuiRSyntaxTextArea.groovy +++ b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/GroovyShellGuiRSyntaxTextArea.groovy @@ -1,314 +1,284 @@ -package net.sf.jremoterun.utilities.nonjdk.rstacore - -import groovy.transform.CompileStatic -import net.sf.jremoterun.utilities.JrrClassUtils -import org.fife.rsta.ac.LanguageSupportFactory -import org.fife.rsta.ac.java.JavaLanguageSupport -import org.fife.rsta.ac.java.custom.RSyntaxTextAreaCodeAssist -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea -import org.fife.ui.rsyntaxtextarea.SyntaxConstants -import org.fife.ui.rtextarea.RTextScrollPane - -import javax.swing.JMenuItem -import javax.swing.JPopupMenu -import javax.swing.ScrollPaneConstants -import javax.swing.SwingUtilities -import javax.swing.text.BadLocationException -import javax.swing.text.Caret -import java.awt.Color -import java.awt.Component -import java.awt.event.FocusAdapter -import java.awt.event.FocusEvent -import java.util.logging.Level -import java.util.logging.Logger - -@CompileStatic -public abstract class GroovyShellGuiRSyntaxTextArea { - - private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - - public String generatedClassName; - - private ArrayList menuItems = new ArrayList(); - - private long editsTry = 0; - - final RSyntaxTextAreaCodeAssist textArea; - - final RTextScrollPane scrollPane; - - public GroovyShellGuiRSyntaxTextArea() { - textArea = createTextArea(); - scrollPane = new RTextScrollPane(textArea, true); - setEditable(true); - textArea.setTabSize(2); - scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); - scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - scrollPane.setIconRowHeaderEnabled(true); - scrollPane.addFocusListener(new FocusAdapter() { - - @Override - public void focusGained(final FocusEvent e) { - textArea.requestFocusInWindow(); - } - }); - codeExecutionHilighter.start(); - textArea.setCodeFoldingEnabled(true); - } - - protected RSyntaxTextAreaCodeAssist createTextArea() { - return new RSyntaxTextAreaCodeAssistWithCustMenu() { - @Override - void appendFoldingMenu2(JPopupMenu popupMenu) { - appendFoldingMenu3(popupMenu); - } - }; - } - - void appendFoldingMenu3(JPopupMenu popupMenu){ - for (JMenuItem menuItem : menuItems) { - popupMenu.add(menuItem); - } - - } - - public void setText(String text) { - textArea.setText(text); - textArea.setHyperlinksEnabled(true); - scrollPane.setLineNumbersEnabled(true); - textArea.setHighlightCurrentLine(false); - - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - textArea.select(0, 0); - if (!isEditable()) { - editsTry++; - if (editsTry > 5) { - // discarding for avoiding memory leak - textArea.discardAllEdits(); - editsTry = 0; - } - } - } - -// abstract String getScriptText() throws IOException - - public boolean requestFocusInWindow() { - return textArea.requestFocusInWindow(); - - } - - public void requestFocus() { - textArea.requestFocus(); - } - - public String getText() { - String text = textArea.getText(); - text = text.replace("\r\n", "\n").replace("\r", "\n"); - return text; - } - - public String getSelectedText() { - String selectedText = textArea.getSelectedText(); - if (selectedText == null) { - return null; - } - selectedText = selectedText.replace("\r\n", "\n").replace("\r", "\n"); - return selectedText; - } - - public void addLangSupport() throws Exception { - RstaLangSupportStatic langSupport = RstaLangSupportStatic.langSupport; - langSupport.init(); -// RSyntaxTextArea textArea = this.getTextArea(); - JavaLanguageSupport groovyLanguageSupport; - groovyLanguageSupport = (JavaLanguageSupport) LanguageSupportFactory.get() - .getSupportFor(SyntaxConstants.SYNTAX_STYLE_JAVA); - groovyLanguageSupport.setJarManager langSupport.addFileSourceToRsta.jarManager - textArea.groovyLanguageSupport = groovyLanguageSupport - groovyLanguageSupport.install(textArea); - -// JrrClassUtils.setFieldValue(langSupport.groovyLanguageSupport, "jarManager", -// langSupport.addFileSourceToRsta.jarManager); - textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_GROOVY); - textArea.addSupport(); -// textArea.groovyLanguageSupport = langSupport.groovyLanguageSupport; - if(langSupport.osInegrationClient!=null) { - textArea.addExternalMemberClickedListener( - new RstaOpenMember(langSupport.osInegrationClient)); - } - } - - public Component getScriptSource() { - return scrollPane; - } - - public void prepareAndRun() { - textArea.removeAllLineHighlights(); - } - - public void highLightLineAsError(int line) throws BadLocationException { - textArea.addLineHighlight(line, Color.PINK); - } - - private void highLightCurrentExecutingLine(int line) throws BadLocationException { - textArea.removeAllLineHighlights(); - textArea.addLineHighlight(line, Color.cyan); - } - - public volatile Thread codeThread; - - public void codeStarted() { - codeThread = Thread.currentThread(); - synchronized (codeExecutionHilighter) { - codeExecutionHilighter.notify(); - } - } - - public void additionalHilighter() { - - } - - boolean isStopCodeExecutionHilighterThread = false - - private Thread codeExecutionHilighter = new Thread("CodeExecutionHilighter") { - @Override - public void run() { - while (!isStopCodeExecutionHilighterThread) { - try { - codeExecutionHilighterM() - } catch (Exception e) { - log.log(Level.SEVERE, "", e); - } - } - } - }; - - void codeExecutionHilighterM(){ - Thread codeThread2 = codeThread; - if (codeThread2 == null) { - log.info("thread value is null"); - } else { - StackTraceElement[] stackTraces = codeThread2.getStackTrace(); - final int lineNumber2 = getLineNumberFromStackTrace(stackTraces); - if (lineNumber2 >= 0) { - SwingUtilities.invokeLater { - try { - if (codeThread != null) { - highLightCurrentExecutingLine(lineNumber2); - } - } catch (Exception e) { - log.log(Level.SEVERE, "", e); - } - } - - } - additionalHilighter(); - } - synchronized (codeExecutionHilighter) { - if (codeThread2 == null) { - codeExecutionHilighter.wait(); - } else { - codeExecutionHilighter.wait(1000); - } - } - } - - void stopCodeExecutionHilighterThread(){ - isStopCodeExecutionHilighterThread = true; - synchronized (codeExecutionHilighter){ - codeExecutionHilighter.notifyAll() - } - } - - public int getLineNumberFromStackTrace(StackTraceElement[] stackTraces) { - StackTraceElement stackTraceElementF = null; - for (StackTraceElement stackTraceElement : stackTraces) { - if (stackTraceElement.getClassName().startsWith(generatedClassName)) { - stackTraceElementF = stackTraceElement; - break; - } - } - if (stackTraceElementF != null) { - int lineNumber = stackTraceElementF.getLineNumber(); - if (lineNumber > 0) { - final int lineNumber2 = lineNumber - 1; - // log.info(lineNumber2 + ""); - return lineNumber2; - } else { - log.warning("wrong line number : " + stackTraceElementF); - } - } - return -1; - } - - public void codeStopped() { - codeThread = null; - SwingUtilities.invokeLater(new Runnable() { - public void run() { - textArea.removeAllLineHighlights(); - } - }); - } - - public int getSelectionStart() { - return textArea.getSelectionStart(); - } - - public void runAfterInSwingThread() { - - } - - public void close() { - } - - public boolean isEditable() { - return textArea.isEditable(); - } - - public void setEditable(final boolean editable) { - textArea.setEditable(editable); - } - - public void setColumns(final int i) { - textArea.setColumns(i); - - } - - public RTextScrollPane getScrollPane() { - return scrollPane; - } - - public Component getComponent() { - return scrollPane; - } - - public void replaceRange(String value, int start, int end) { - textArea.replaceRange(value, start, end); - - } - - public Caret getCaret() { - return textArea.getCaret(); - } - - public void setCurstorToStart() { - textArea.select(0, 0); - } - - public void setSyntaxEditingStyle(String newStyle) { - textArea.setSyntaxEditingStyle(newStyle); - - } - - public void setLineNumbersEnabled(boolean selected) { - scrollPane.setLineNumbersEnabled(selected); - - } - - public void addMenuItem(JMenuItem menuItem) { - menuItems.add(menuItem); - textArea.addMenuItem(menuItem); - } - -} +package net.sf.jremoterun.utilities.nonjdk.rstacore + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import org.fife.rsta.ac.LanguageSupportFactory +import org.fife.rsta.ac.java.JavaLanguageSupport +import org.fife.rsta.ac.java.custom.RSyntaxTextAreaCodeAssist +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea +import org.fife.ui.rsyntaxtextarea.SyntaxConstants +import org.fife.ui.rtextarea.RTextScrollPane + +import javax.swing.JMenuItem +import javax.swing.JPopupMenu +import javax.swing.ScrollPaneConstants +import javax.swing.SwingUtilities +import javax.swing.text.BadLocationException +import javax.swing.text.Caret +import java.awt.Color +import java.awt.Component +import java.awt.event.FocusAdapter +import java.awt.event.FocusEvent +import java.util.logging.Level +import java.util.logging.Logger + +@CompileStatic +public abstract class GroovyShellGuiRSyntaxTextArea { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public String generatedClassName; + + private ArrayList menuItems = new ArrayList(); + + final RSyntaxTextAreaCodeAssistUndoFix textArea; + + public GroovyShellGuiRSyntaxTextArea() { + textArea = createTextArea(); + textArea.scrollPane = new RTextScrollPane(textArea, true); + setEditable(true); + textArea.setTabSize(2); + textArea.scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + textArea.scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + textArea.scrollPane.setIconRowHeaderEnabled(true); + textArea.scrollPane.addFocusListener(new FocusAdapter() { + + @Override + public void focusGained(final FocusEvent e) { + textArea.requestFocusInWindow(); + } + }); + codeExecutionHilighter.start(); + textArea.setCodeFoldingEnabled(true); + } + + protected RSyntaxTextAreaCodeAssistUndoFix createTextArea() { + return new RSyntaxTextAreaCodeAssistUndoFix() { + @Override + void appendFoldingMenu2(JPopupMenu popupMenu) { + appendFoldingMenu3(popupMenu); + } + }; + } + + protected void appendFoldingMenu3(JPopupMenu popupMenu){ + for (JMenuItem menuItem : menuItems) { + popupMenu.add(menuItem); + } + + } + + void addLangSupport(){ + textArea.addLangSupport() + } + + @Deprecated + public void setText(String text) { + textArea.setText(text); + } + + +// abstract String getScriptText() throws IOException + + boolean requestFocusInWindow() { + return textArea.requestFocusInWindow(); + + } + + public void requestFocus() { + textArea.requestFocus(); + } + + @Deprecated + public String getText() { + return textArea.getTextNormalized(); + } + + public String getSelectedText() { + String selectedText = textArea.getSelectedText(); + if (selectedText == null) { + return null; + } + selectedText = RSyntaxTextAreaCodeAssistUndoFix.nornalizeText(selectedText); + return selectedText; + } + + + // used ? + public Component getScriptSource() { + return textArea.scrollPane; + } + + // t:dual + public void prepareAndRun() { + textArea.removeAllLineHighlights(); + } + + // t:dual + public void highLightLineAsError(int line) throws BadLocationException { + textArea.addLineHighlight(line, Color.PINK); + } + + // t:dual + protected void highLightCurrentExecutingLine(int line) throws BadLocationException { + textArea.removeAllLineHighlights(); + textArea.addLineHighlight(line, Color.cyan); + } + + public volatile Thread codeThread; + + public void codeStarted() { + codeThread = Thread.currentThread(); + synchronized (codeExecutionHilighter) { + codeExecutionHilighter.notify(); + } + } + + protected void additionalHilighter() { + + } + + boolean isStopCodeExecutionHilighterThread = false + + private Thread codeExecutionHilighter = new Thread("CodeExecutionHilighter") { + @Override + public void run() { + while (!isStopCodeExecutionHilighterThread) { + try { + codeExecutionHilighterM() + } catch (Exception e) { + log.log(Level.SEVERE, "", e); + } + } + } + }; + + void codeExecutionHilighterM(){ + Thread codeThread2 = codeThread; + if (codeThread2 == null) { + log.info("thread value is null"); + } else { + StackTraceElement[] stackTraces = codeThread2.getStackTrace(); + final int lineNumber2 = getLineNumberFromStackTrace(stackTraces); + if (lineNumber2 >= 0) { + SwingUtilities.invokeLater { + try { + if (codeThread != null) { + highLightCurrentExecutingLine(lineNumber2); + } + } catch (Exception e) { + log.log(Level.SEVERE, "", e); + } + } + + } + additionalHilighter(); + } + synchronized (codeExecutionHilighter) { + if (codeThread2 == null) { + codeExecutionHilighter.wait(); + } else { + codeExecutionHilighter.wait(1000); + } + } + } + + void stopCodeExecutionHilighterThread(){ + isStopCodeExecutionHilighterThread = true; + synchronized (codeExecutionHilighter){ + codeExecutionHilighter.notifyAll() + } + } + + public int getLineNumberFromStackTrace(StackTraceElement[] stackTraces) { + StackTraceElement stackTraceElementF = null; + for (StackTraceElement stackTraceElement : stackTraces) { + if (stackTraceElement.getClassName().startsWith(generatedClassName)) { + stackTraceElementF = stackTraceElement; + break; + } + } + if (stackTraceElementF != null) { + int lineNumber = stackTraceElementF.getLineNumber(); + if (lineNumber > 0) { + final int lineNumber2 = lineNumber - 1; + // log.info(lineNumber2 + ""); + return lineNumber2; + } else { + log.warning("wrong line number : " + stackTraceElementF); + } + } + return -1; + } + + void codeStopped() { + codeThread = null; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + textArea.removeAllLineHighlights(); + } + }); + } + + public int getSelectionStart() { + return textArea.getSelectionStart(); + } + + public void runAfterInSwingThread() { + + } + + public void close() { + } + + public boolean isEditable() { + return textArea.isEditable(); + } + + public void setEditable(final boolean editable) { + textArea.setEditable(editable); + } + + public void setColumns(final int i) { + textArea.setColumns(i); + + } + + @Deprecated + public RTextScrollPane getScrollPane() { + return textArea.scrollPane; + } + + public Component getComponent() { + return textArea.scrollPane; + } + + public void replaceRange(String value, int start, int end) { + textArea.replaceRange(value, start, end); + + } + + public Caret getCaret() { + return textArea.getCaret(); + } + + public void setCurstorToStart() { + textArea.select(0, 0); + } + + public void setSyntaxEditingStyle(String newStyle) { + textArea.setSyntaxEditingStyle(newStyle); + + } + + public void setLineNumbersEnabled(boolean selected) { + textArea.scrollPane.setLineNumbersEnabled(selected); + + } + + public void addMenuItem(JMenuItem menuItem) { + menuItems.add(menuItem); + textArea.addMenuItem(menuItem); + } + +} diff --git a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/LogImprovedJarManager.groovy b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/LogImprovedJarManager.groovy new file mode 100644 index 00000000..5110f60b --- /dev/null +++ b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/LogImprovedJarManager.groovy @@ -0,0 +1,28 @@ +package net.sf.jremoterun.utilities.nonjdk.rstacore + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import org.fife.rsta.ac.java.JarManager; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.CompletionProvider; + +import java.util.Set; +import java.util.logging.Logger; + +@CompileStatic +public class LogImprovedJarManager extends JarManager { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + + @Override + public void addCompletions(CompletionProvider p, String text, Set addTo) { + if (text.length() > 0 && text.length() < 3) { + log.fine("text too short : " + text); + } else { + super.addCompletions(p, text, addTo); + } + } + +} diff --git a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/OpenInBrowserLinkGeneratorResult.groovy b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/OpenInBrowserLinkGeneratorResult.groovy new file mode 100644 index 00000000..402c0e50 --- /dev/null +++ b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/OpenInBrowserLinkGeneratorResult.groovy @@ -0,0 +1,26 @@ +package net.sf.jremoterun.utilities.nonjdk.rstacore + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.fife.ui.rsyntaxtextarea.LinkGeneratorResult + +import javax.swing.event.HyperlinkEvent; +import java.util.logging.Logger; + +@CompileStatic +abstract class OpenInBrowserLinkGeneratorResult implements LinkGeneratorResult{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + int sourceOffset + String url; + + OpenInBrowserLinkGeneratorResult(int sourceOffset, String url) { + this.sourceOffset = sourceOffset + this.url = url + } + + @Override + int getSourceOffset() { + return sourceOffset + } +} diff --git a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RSyntaxTextAreaCodeAssistUndoFix.groovy b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RSyntaxTextAreaCodeAssistUndoFix.groovy new file mode 100644 index 00000000..80e303d5 --- /dev/null +++ b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RSyntaxTextAreaCodeAssistUndoFix.groovy @@ -0,0 +1,81 @@ +package net.sf.jremoterun.utilities.nonjdk.rstacore + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.fife.rsta.ac.LanguageSupportFactory +import org.fife.rsta.ac.java.JavaLanguageSupport +import org.fife.rsta.ac.java.custom.RSyntaxTextAreaCodeAssist +import org.fife.ui.rsyntaxtextarea.SyntaxConstants +import org.fife.ui.rtextarea.RTextScrollPane; + +import java.util.logging.Logger; + +@CompileStatic +abstract class RSyntaxTextAreaCodeAssistUndoFix extends RSyntaxTextAreaCodeAssistWithCustMenu { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + protected long editsTry = 0; + private RSyntaxTextAreaCodeAssist textArea = this; + + RTextScrollPane scrollPane; + + @Override + public void setText(String text) { + super.setText(text); + textArea.setHyperlinksEnabled(true); + scrollPane.setLineNumbersEnabled(true); + textArea.setHighlightCurrentLine(false); + + textArea.setLineWrap(true); + textArea.setWrapStyleWord(true); + textArea.select(0, 0); + if (!isEditable()) { + editsTry++; + if (editsTry > 5) { + // discarding for avoiding memory leak + textArea.discardAllEdits(); + editsTry = 0; + } + } + } + + @Deprecated + @Override + String getText() { + return getTextNormalized() + } + + public String getTextNormalized() { + String text = super.getText(); + text = nornalizeText(text); + return text; + } + + static String nornalizeText(String text){ + return text.replace("\r\n", "\n").replace("\r", "\n"); + } + + void addLangSupport() throws Exception { + RstaLangSupportStatic langSupport = RstaLangSupportStatic.langSupport; + langSupport.init(); +// RSyntaxTextArea textArea = this.getTextArea(); + JavaLanguageSupport groovyLanguageSupport; + groovyLanguageSupport = (JavaLanguageSupport) LanguageSupportFactory.get() + .getSupportFor(SyntaxConstants.SYNTAX_STYLE_JAVA); + groovyLanguageSupport.setJarManager langSupport.addFileSourceToRsta.jarManager + textArea.groovyLanguageSupport = groovyLanguageSupport + groovyLanguageSupport.install(textArea); + +// JrrClassUtils.setFieldValue(langSupport.groovyLanguageSupport, "jarManager", +// langSupport.addFileSourceToRsta.jarManager); + textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_GROOVY); + textArea.addSupport(); +// textArea.groovyLanguageSupport = langSupport.groovyLanguageSupport; + if(langSupport.osInegrationClient!=null) { + textArea.addExternalMemberClickedListener( + new RstaOpenMember(langSupport.osInegrationClient)); + } + } + + +} diff --git a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RSyntaxTextAreaCodeAssistWithCustMenu.groovy b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RSyntaxTextAreaCodeAssistWithCustMenu.groovy index 376a8766..7e674134 100644 --- a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RSyntaxTextAreaCodeAssistWithCustMenu.groovy +++ b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RSyntaxTextAreaCodeAssistWithCustMenu.groovy @@ -1,23 +1,23 @@ -package net.sf.jremoterun.utilities.nonjdk.rstacore; - -import net.sf.jremoterun.utilities.JrrClassUtils -import org.fife.rsta.ac.java.custom.RSyntaxTextAreaCodeAssist - -import javax.swing.JPopupMenu; -import java.util.logging.Logger; -import groovy.transform.CompileStatic; - - -@CompileStatic -abstract class RSyntaxTextAreaCodeAssistWithCustMenu extends RSyntaxTextAreaCodeAssist{ - - private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - - protected void appendFoldingMenu(JPopupMenu popupMenu) { - super.appendFoldingMenu(popupMenu); - appendFoldingMenu2(popupMenu); - }; - - abstract void appendFoldingMenu2(JPopupMenu popupMenu); - -} +package net.sf.jremoterun.utilities.nonjdk.rstacore; + +import net.sf.jremoterun.utilities.JrrClassUtils +import org.fife.rsta.ac.java.custom.RSyntaxTextAreaCodeAssist + +import javax.swing.JPopupMenu; +import java.util.logging.Logger; +import groovy.transform.CompileStatic; + + +@CompileStatic +abstract class RSyntaxTextAreaCodeAssistWithCustMenu extends RSyntaxTextAreaCodeAssist{ + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + protected void appendFoldingMenu(JPopupMenu popupMenu) { + super.appendFoldingMenu(popupMenu); + appendFoldingMenu2(popupMenu); + }; + + abstract void appendFoldingMenu2(JPopupMenu popupMenu); + +} diff --git a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RstaLangSupportStatic.groovy b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RstaLangSupportStatic.groovy index d79a106f..ef776348 100644 --- a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RstaLangSupportStatic.groovy +++ b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RstaLangSupportStatic.groovy @@ -8,6 +8,7 @@ import net.sf.jremoterun.utilities.classpath.ClassPathCalculatorWithAdder import net.sf.jremoterun.utilities.classpath.MavenCommonUtils import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import org.apache.commons.lang3.SystemUtils import org.fife.rsta.ac.java.JarManager import org.fife.rsta.ac.java.buildpath.LibraryInfo import org.fife.ui.autocomplete.Completion @@ -32,22 +33,20 @@ public class RstaLangSupportStatic { public OsInegrationClientI osInegrationClient + public static boolean addJfrIfExistS = true + public ClassPathCalculatorWithAdder classPathCalculatorGroovy = new ClassPathCalculatorWithAdder(); + + JarManager createJarManager(){ + return new LogImprovedJarManager() + } + public void init() throws Exception { if (addFileSourceToRsta != null) { return; } - JarManager jarManager = new JarManager() { - @Override - public void addCompletions(CompletionProvider p, String text, Set addTo) { - if (text.length() > 0 && text.length() < 3) { - log.fine("text too short : " + text); - } else { - super.addCompletions(p, text, addTo); - } - } - }; + JarManager jarManager = createJarManager() try { LibraryInfo info = LibraryInfo.getMainJreJarInfo(); if(info ==null){ @@ -68,6 +67,15 @@ public class RstaLangSupportStatic { } + void addJfrJarIfExist(){ + File javaHome = SystemUtils.getJavaHome(); + assert javaHome.exists(); + File jfrJar = javaHome.child('lib/jfr.jar'); + if(jfrJar.exists()) { + classPathCalculatorGroovy.filesAndMavenIds.add(jfrJar) + } + } + void addEntryInFly(Object obj){ GroovyMethodRunnerParams.gmrp.addFilesToClassLoader.add(obj) addFileSourceToRsta.add(obj) @@ -93,7 +101,7 @@ public class RstaLangSupportStatic { ClassLoader currentClassLoader = JrrClassUtils.getCurrentClassLoader(); if (currentClassLoader instanceof URLClassLoader) { URLClassLoader urlClassLoader = (URLClassLoader) currentClassLoader; - classPathCalculatorGroovy.addClassPathFromURLClassLoader(urlClassLoader); + classPathCalculatorGroovy.addFilesToClassLoaderGroovySave.addClassPathFromURLClassLoader(urlClassLoader); } else { log.info("non url classloader"); } @@ -119,6 +127,9 @@ public class RstaLangSupportStatic { } else { classPathCalculatorGroovy.filesAndMavenIds.add toolsJarFile } + if(addJfrIfExistS){ + addJfrJarIfExist() + } classPathCalculatorGroovy.filesAndMavenIds.add DropshipClasspath.groovy diff --git a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RstaOpenMember.groovy b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RstaOpenMember.groovy index a7ea489f..08fb7e19 100644 --- a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RstaOpenMember.groovy +++ b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/RstaOpenMember.groovy @@ -1,53 +1,53 @@ -package net.sf.jremoterun.utilities.nonjdk.rstacore - -import groovy.transform.CompileStatic; -import net.sf.jremoterun.utilities.JrrClassUtils; -import net.sf.jremoterun.utilities.OsInegrationClientI; -import org.fife.rsta.ac.java.ExternalMemberClickedListener; -import org.fife.rsta.ac.java.classreader.FieldInfo; -import org.fife.rsta.ac.java.classreader.MethodInfo; - -import java.util.logging.Level; -import java.util.logging.Logger; - -@CompileStatic -public class RstaOpenMember implements ExternalMemberClickedListener { - private static final Logger log = Logger.getLogger(JrrClassUtils.getCurrentClass().getName()); - - final OsInegrationClientI osInegrationClient; - - public RstaOpenMember(OsInegrationClientI osInegrationClient) { - this.osInegrationClient = osInegrationClient; - } - - public void openClass(String className) { - log.info(className); - try { - osInegrationClient.openClass(className); - } catch (Exception e) { - log.log(Level.SEVERE, className, e); - } - - } - - public void gotoMethodInClass(String className, MethodInfo methodInfo) { - log.info(className); - log.info(methodInfo.getReturnTypeFull()+" "+methodInfo.getReturnTypeString(false)); - try { - osInegrationClient.openMethod(className, methodInfo.getName(), methodInfo.getParameterCount()); - } catch (Exception e) { - log.log(Level.SEVERE, className, e); - } - } - - public void gotoFieldInClass(String className, FieldInfo fieldInfo) { - log.info(className); - log.info(fieldInfo.getTypeString(false)+" "+fieldInfo.getTypeString(true)); - try { - osInegrationClient.openField(className, fieldInfo.getName()); - } catch (Exception e) { - log.log(Level.SEVERE, className, e); - } - } - -} +package net.sf.jremoterun.utilities.nonjdk.rstacore + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.OsInegrationClientI; +import org.fife.rsta.ac.java.ExternalMemberClickedListener; +import org.fife.rsta.ac.java.classreader.FieldInfo; +import org.fife.rsta.ac.java.classreader.MethodInfo; + +import java.util.logging.Level; +import java.util.logging.Logger; + +@CompileStatic +public class RstaOpenMember implements ExternalMemberClickedListener { + private static final Logger log = Logger.getLogger(JrrClassUtils.getCurrentClass().getName()); + + final OsInegrationClientI osInegrationClient; + + public RstaOpenMember(OsInegrationClientI osInegrationClient) { + this.osInegrationClient = osInegrationClient; + } + + public void openClass(String className) { + log.info(className); + try { + osInegrationClient.openClass(className); + } catch (Exception e) { + log.log(Level.SEVERE, className, e); + } + + } + + public void gotoMethodInClass(String className, MethodInfo methodInfo) { + log.info(className); + log.info(methodInfo.getReturnTypeFull()+" "+methodInfo.getReturnTypeString(false)); + try { + osInegrationClient.openMethod(className, methodInfo.getName(), methodInfo.getParameterCount()); + } catch (Exception e) { + log.log(Level.SEVERE, className, e); + } + } + + public void gotoFieldInClass(String className, FieldInfo fieldInfo) { + log.info(className); + log.info(fieldInfo.getTypeString(false)+" "+fieldInfo.getTypeString(true)); + try { + osInegrationClient.openField(className, fieldInfo.getName()); + } catch (Exception e) { + log.log(Level.SEVERE, className, e); + } + } + +} diff --git a/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/TextAssociatedLinkGenerator.groovy b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/TextAssociatedLinkGenerator.groovy new file mode 100644 index 00000000..19dd9a55 --- /dev/null +++ b/src-rsta-core/net/sf/jremoterun/utilities/nonjdk/rstacore/TextAssociatedLinkGenerator.groovy @@ -0,0 +1,74 @@ +package net.sf.jremoterun.utilities.nonjdk.rstacore + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.fife.ui.rsyntaxtextarea.LinkGenerator +import org.fife.ui.rsyntaxtextarea.LinkGeneratorResult +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; + +import java.util.logging.Logger; +import org.fife.ui.rsyntaxtextarea.Token; + +@CompileStatic +abstract class TextAssociatedLinkGenerator implements LinkGenerator{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + // public HashMap links = new HashMap<>() + + + @Override + LinkGeneratorResult isLinkAtOffset(RSyntaxTextArea textArea, int offs) { + Token token = findToken(textArea, offs) + int start = token.getOffset() + int end = token.getEndOffset() + int length = end - start + if(length == 0){ + log.info "length is zero at off = ${offs}" + return null + } + String text = textArea.getText(start,length) + return isLinkAtOffset2(textArea,offs,text) + } + + abstract LinkGeneratorResult isLinkAtOffset2(RSyntaxTextArea textArea3, int offs,String text) +// text = text.trim() +// LinkGeneratorResult generatorResult = links.get(text) +// return generatorResult + + + + Token findToken( RSyntaxTextArea textArea2,int offset){ + int line = textArea2.getLineOfOffset(offset) + Token token = textArea2.getTokenListForLine(line) + return findTokenNext(token,offset) + } + + Token findTokenNext(Token startToken,int offset){ + Token token1 = getNearestPaintableToken(startToken) + if(token1==null){ + log.info "failed find token at offset ${offset}" + return null + } + if(token1.containsPosition(offset)){ + return token1 + } + return findTokenNext(startToken.getNextToken(),offset) + } + + static Token getNearestPaintableToken(Token token){ + if(token==null){ + return null + } + if(token.isPaintable()){ + return token + } + Token nextToken = token.getNextToken() + if(nextToken==null){ + return null + } +// if(nextToken.isPaintable()){ +// return nextToken +// } + return getNearestPaintableToken(nextToken) + } +} diff --git a/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunner.groovy b/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunner.groovy index cdce0973..05fda8d8 100644 --- a/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunner.groovy +++ b/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunner.groovy @@ -37,9 +37,32 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { } + GroovyShellGuiRSyntaxTextArea textAreaRunner = this; +// new GroovyShellGuiRSyntaxTextArea(){ +// +// @Override +// void additionalHilighter() { +// super.additionalHilighter() +// RstaRunner.this.additionalHilighter() +// } +// +// @Override +// void codeStopped() { +// super.codeStopped() +// RstaRunner.this.codeStopped() +// } +// +// @Override +// void codeStarted() { +// super.codeStarted() +// RstaRunner.this.codeStarted(); +// } +// } + JButton runButton = new JButton(RunnerStatus.Run.name()) JButton saveToFileButton = new JButton("Save to file") Thread thread; + boolean onStopCallInterrupt; boolean runInSwingThread = false; JTextField progressLable = new JTextField() { @@ -50,6 +73,17 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { } +// void codeStarted(){ +// +// } + +// void codeStopped(){ +// +// } + +// void additionalHilighter() { +// +// } Component getMainPanel() { return panel @@ -57,7 +91,7 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { boolean requestFocusInWindow2() { - return getComponent().requestFocusInWindow() + return textAreaRunner.getComponent().requestFocusInWindow() } ClassLoader classLoader2 = JrrClassUtils.getCurrentClassLoader() @@ -69,39 +103,56 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { // RunnerStatus runnerStatus = RunnerStatus.Stop public Runnable codeFinisedFineListener; - //File file + + public File fileWithConfig RstaRunner(File file) { - this(file.text) + this(checkFileExist2(file).text) + fileWithConfig = file panelButtons.add(saveToFileButton) saveToFileButton.addActionListener { - file.text = getText(); + fileWithConfig.text = textAreaRunner.textArea.getTextNormalized(); } } + + static File checkFileExist2(File file){ + JrrUtilities.checkFileExist(file) + if(!file.isFile()){ + throw new IOException("Bad file : ${file}") + } + return file + } + RstaRunner(String text2) { super() runButton.setMnemonic(KeyEvent.VK_R); panel.add(panelButtons, BorderLayout.NORTH) - panel.add(getComponent(), BorderLayout.CENTER) + panel.add(textAreaRunner.getComponent(), BorderLayout.CENTER) progressLable.setEditable(false) progressLable.setColumns(20) panelButtons.add(progressLable) panelButtons.add(runButton) addLangSupport() - setText(text2) + textAreaRunner.textArea.setText(text2) runButton.addActionListener { runButtonPressed() } } - private void prepareAndRun2() { + +// @Override +// public void addLangSupport() throws Exception { +// textArea.addLangSupport() +// } + + void prepareAndRun2(Object param) { stopFlag = false; - prepareAndRun() + textAreaRunner.prepareAndRun() progressLable.text = "" - runButton.enabled = false + runButton.setEnabled(false) Runnable r = { - runCode() + runCode(param) } if (runInSwingThread) { r.run() @@ -112,6 +163,12 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { } + void enableButtons(){ + + } + void disableButtons(){ + + } private void runButtonPressed() { log.fine("Start time : ${new Date()}"); @@ -121,10 +178,10 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { case RunnerStatus.Stop: runButton.setText(RunnerStatus.Stoping.name()); runButton.setEnabled(false); - stopFlag = true; + onStopRequest() break; case RunnerStatus.Run: - prepareAndRun2(); + prepareAndRun2(null); break; case RunnerStatus.Stoping: log.info("still stopping"); @@ -132,6 +189,20 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { } } + void onStopRequest(){ + stopFlag = true; + if(onStopCallInterrupt) { + interruptThread(); + } + } + + void interruptThread(){ + Thread thread2 = thread; + if(thread2!=null && thread2!= Thread.currentThread()) { + thread2.interrupt(); + } + } + void setStatus(String status) { SwingUtilities.invokeLater { @@ -139,35 +210,42 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { } } - void runCode() { + // t:dual + String getTextToRun(){ + return textAreaRunner.textArea.getTextNormalized() + } + + void runCode(Object param) { try { - String text2 = getText().replace("\r\n", "\n").replace("\r", "\n"); + StopRequestIndicator.stopRequest.set(this) + String text2 = getTextToRun(); Thread.currentThread().setContextClassLoader(classLoader2); GroovyClassLoader classLoader = createGroovyClassLoader(); Thread.currentThread().setContextClassLoader(classLoader); - String genClassName = generatedClassName + String genClassName = textAreaRunner.generatedClassName if (genClassName == null) { genClassName = 'script' + System.currentTimeMillis() + - Math.abs(text.hashCode()) + '.groovy' + Math.abs(text2.hashCode()) + '.groovy' } - generatedClassName = genClassName + textAreaRunner.generatedClassName = genClassName Class parseClass = classLoader.parseClass(text2, genClassName); // Thread.currentThread().setContextClassLoader(parseClass.getClassLoader()); - generatedClassName = parseClass.getName() - codeStarted() - runGroovyClass(parseClass) + textAreaRunner.generatedClassName = parseClass.getName() + textAreaRunner.codeStarted() + runGroovyClass(parseClass,param) if (codeFinisedFineListener != null) { codeFinisedFineListener.run() } - codeStopped() + textAreaRunner.codeStopped() } catch (Throwable e) { - codeStopped() + textAreaRunner.codeStopped() JrrUtilities.showException("", e) SwingUtilities.invokeLater { parseException(e) } } finally { SwingUtilities.invokeLater { - runButton.enabled = true + runButton.setEnabled( true) runButton.setText(RunnerStatus.Run.name()) + enableButtons() } } } @@ -185,18 +263,18 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { if (e2 instanceof MultipleCompilationErrorsException) { MultipleCompilationErrorsException f1 = (MultipleCompilationErrorsException) e2; ErrorCollector errorCollector = f1.getErrorCollector(); - java.util.List errors = errorCollector.getErrors(); + java.util.List errors = (List)errorCollector.getErrors(); if (errors.size() > 0) { Message message = errors.get(0); if (message instanceof SyntaxErrorMessage) { SyntaxErrorMessage syntaxErrorMessage = (SyntaxErrorMessage) message; SyntaxException cause = syntaxErrorMessage.getCause(); - log.info "${cause.getSourceLocator()} ${generatedClassName}" - if (generatedClassName == cause.getSourceLocator()) { + log.info "${cause.getSourceLocator()} ${textAreaRunner.generatedClassName}" + if (textAreaRunner.generatedClassName == cause.getSourceLocator()) { int line = cause.getStartLine(); log.info "${line}" line += -1; - highLightLineAsError(line); + textAreaRunner.highLightLineAsError(line); return } else { log.info("ignore SyntaxException as another groovy script : " + cause.getSourceLocator()); @@ -208,17 +286,17 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { StackTraceElement[] stackTraces = rootException.getStackTrace(); final int lineNumber2 = getLineNumberFromStackTrace4(stackTraces); if (lineNumber2 != -1) { - highLightLineAsError(lineNumber2); + textAreaRunner.highLightLineAsError(lineNumber2); } } int getLineNumberFromStackTrace4(StackTraceElement[] stackTraces) { - if(generatedClassName==null ||generatedClassName.length()==0){ + if(textAreaRunner.generatedClassName==null ||textAreaRunner.generatedClassName.length()==0){ return -1; } StackTraceElement stackTraceElementF = null; for (StackTraceElement stackTraceElement : stackTraces) { - if (stackTraceElement.getClassName().startsWith(generatedClassName)) { + if (stackTraceElement.getClassName().startsWith(textAreaRunner.generatedClassName)) { stackTraceElementF = stackTraceElement; break; } @@ -232,7 +310,7 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { return -1; } - private Object runGroovyClass(Class scriptClass) throws Exception { + Object runGroovyClass(Class scriptClass,Object param) throws Exception { groovyScriptObject = scriptClass.newInstance() as RstaScriptHelper; groovyScriptObject.runner = this; assert groovyScriptObject.runner != null @@ -242,14 +320,19 @@ class RstaRunner extends GroovyShellGuiRSyntaxTextArea { if (runButton.isEnabled()) { log.info("not enabled ${runButton.getText()}") } else { + disableButtons() runButton.setText(RunnerStatus.Stop.name()); runButton.setEnabled(true) } } - + preRunAfterScriptLoaded() groovyScriptObject.run() return null; } + void preRunAfterScriptLoaded(){ + + } + } \ No newline at end of file diff --git a/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace.groovy b/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace.groovy index dfd8ad07..e28f2f9f 100644 --- a/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace.groovy +++ b/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace.groovy @@ -16,13 +16,12 @@ class RstaRunnerWithStackTrace extends RstaRunner { StackTraceTextArea textAreaStackTrace = new StackTraceTextArea() - List ignoreClasses = ['java.awt', 'javax.swing','groovy.lang.Closure.']; + List ignoreClasses = ['java.awt', 'javax.swing', 'groovy.lang.Closure.']; - JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,panel,textAreaStackTrace.scrollPane - ) + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panel, textAreaStackTrace.scrollPane); RstaRunnerWithStackTrace(File file) { - super(file) + super(checkFileExist2(file)); init3() } @@ -38,24 +37,23 @@ class RstaRunnerWithStackTrace extends RstaRunner { ignoreClasses.addAll(JrrClassUtils.ignoreClassesForCurrentClass) textAreaStackTrace.textArea.setColumns(20) splitPane.setDividerLocation(1.0d) - SwingUtilities.invokeLater{ + SwingUtilities.invokeLater { splitPane.setDividerLocation(1.0d) } } @Override - Component getMainPanel(){ + Component getMainPanel() { return splitPane } @Override void additionalHilighter() { - super.additionalHilighter() showSTackTrace() } void showSTackTrace() { - Thread codeThread2 = codeThread + Thread codeThread2 = textAreaRunner.codeThread if (codeThread2 == null) { log.info("thread value is null"); } else { @@ -66,16 +64,15 @@ class RstaRunnerWithStackTrace extends RstaRunner { } String text3 = stackTraces.join('\n'); SwingUtilities.invokeLater { - textAreaStackTrace.textArea.text =text3 + textAreaStackTrace.textArea.text = text3 } } } @Override void codeStopped() { - super.codeStopped() SwingUtilities.invokeLater { - textAreaStackTrace.textArea.text ="" + textAreaStackTrace.textArea.text = "" } } } \ No newline at end of file diff --git a/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace2.groovy b/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace2.groovy index fe09dae7..81f0a738 100644 --- a/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace2.groovy +++ b/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace2.groovy @@ -1,9 +1,13 @@ package net.sf.jremoterun.utilities.nonjdk.rstarunner import groovy.transform.CompileStatic +import net.infonode.docking.DockingWindow import net.infonode.docking.SplitWindow import net.infonode.docking.TabWindow +import net.infonode.docking.title.DockingWindowTitleProvider import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.idwutils.IdwUtils +import net.sf.jremoterun.utilities.nonjdk.idwutils.MyDockingWindowTitleProvider import net.sf.jremoterun.utilities.nonjdk.idwutils.TextAreaAndView import net.sf.jremoterun.utilities.nonjdk.idwutils.ViewAndPanel import net.sf.jremoterun.utilities.nonjdk.log.Log4j2Utils @@ -17,75 +21,98 @@ import java.util.List import java.util.logging.Logger @CompileStatic -class RstaRunnerWithStackTrace2 extends RstaRunner { +class RstaRunnerWithStackTrace2 extends RstaRunnerWithStackTrace3 { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public StackTraceTextArea textAreaStackTrace = new StackTraceTextArea() - StackTraceTextArea textAreaStackTrace = new StackTraceTextArea() - - List ignoreClasses = ['java.awt', 'javax.swing', 'groovy.lang.Closure.']; - - public ViewAndPanel runnerView = new ViewAndPanel("Runner", panel); +// public ViewAndPanel runnerView = new ViewAndPanel("Runner", panel); public ViewAndPanel stackTraceView = new ViewAndPanel("Thread dump"); public TextAreaAndView logsView = new TextAreaAndView("Logs "); - public TabWindow rightPanel = new TabWindow() - public SplitWindow mainPanel3 = new SplitWindow(true, 0.8f, runnerView.view, rightPanel) - - public StringBuilder logs = new StringBuilder() - - Log4j2ThreadAppender log4j2ThreadAppender = new Log4j2ThreadAppender() { - @Override - void filterPassed(LogEvent loggingEvent) { - Date date = new Date(loggingEvent.getTimeMillis()); - modCount++; - String msg = "${sdf.format(date)} ${loggingEvent.message.getFormattedMessage()}\n"; -// System.out.println("got new msg : ${msg}") - logs.append(msg) - } + public TabWindow rightPanel + public SplitWindow mainPanel4; + + public volatile StringBuffer logs = new StringBuffer() + + public JButton cloneButton = new JButton("Clone") + + public SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss") + public volatile int modCount = 0 + +// Log4j2ThreadAppender log4j2ThreadAppender = new Log4j2ThreadAppender() { +// @Override +// void filterPassed(LogEvent loggingEvent) { +// addLogEvent(loggingEvent) +// } +// } + + @Override + void addLogEvent(LogEvent loggingEvent){ + Date date = new Date(loggingEvent.getTimeMillis()); + modCount++; + String msg = "${sdf.format(date)} ${loggingEvent.message.getFormattedMessage()}\n"; + logs.append(msg) } - ; - SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss") - volatile int modCount = 0 + + + SplitWindow getMainPanel3() { + return mainPanel4; + } + RstaRunnerWithStackTrace2(File file) { super(file) - init3() + init4() } RstaRunnerWithStackTrace2(String text2) { super(text2) init3() + init4() } - private void init3() { + void doLoayout() { + rightPanel = new TabWindow() rightPanel.addTab(stackTraceView.view) rightPanel.addTab(logsView.view) + doLayoutCreateMainPanel() + } + + void doLayoutCreateMainPanel() { + mainPanel4 = new SplitWindow(true, 0.8f, runnerView.view, rightPanel) + } + + + protected void init4() { + doLoayout() logsView.textArea.setEditable(false) logsView.textArea.setLineWrap(true) + cloneButton.addActionListener { + onCloneActionListener() + } + panelButtons.add(cloneButton) stackTraceView.panel.add(textAreaStackTrace.scrollPane, BorderLayout.CENTER) -// panel.add(textAreaStackTrace.scrollPane, BorderLayout.EAST) - log.info "scroll pane added" - ignoreClasses.addAll(JrrClassUtils.ignoreClassesForCurrentClass) - Log4j2Utils.rootLogger.addAppender(log4j2ThreadAppender) - log4j2ThreadAppender.translateAllLoggersForExecuterThread = true } - @Override - Component getMainPanel() { - throw new IllegalStateException() + void onCloneActionListener(){ + TabWindow parentIdwWindowSpecial = IdwUtils.getParentIdwWindowSpecial(runnerView.view.getWindowParent(), TabWindow) + RstaRunnerWithStackTrace2 newPanel = new RstaRunnerWithStackTrace2(fileWithConfig) + parentIdwWindowSpecial.addTab(newPanel.getMainPanel3()) + String titleBefore = ' titleBefore ' + DockingWindowTitleProvider titleProvider = getMainPanel3().getWindowProperties().getTitleProvider() + if(titleProvider!=null){ + titleBefore = titleProvider.getTitle(getMainPanel3()) + } + newPanel.getMainPanel3().getWindowProperties().setTitleProvider(new MyDockingWindowTitleProvider(titleBefore)) } @Override - void codeStarted() { + protected void resetLogs() { logs.setLength(0) modCount = 0 analizedModCount = 0 - log4j2ThreadAppender.loggingThread = Thread.currentThread() - // log4j2ThreadAppender.loggingThread = Thread.currentThread() - super.codeStarted() } - @Override void additionalHilighter() { super.additionalHilighter() @@ -94,14 +121,22 @@ class RstaRunnerWithStackTrace2 extends RstaRunner { } volatile int analizedModCount = 0 + public int totalLogSizeTruncated = 0; + public int maxLogSizeTextLength = 20000; + public int maxLogSizeTextNewLength = maxLogSizeTextLength/2 as int; + @Override void showLogs() { // System.out.println("mod count ${modCount} ${analizedModCount}") if (analizedModCount == modCount) { - }else{ + } else { SwingUtilities.invokeLater { analizedModCount = modCount String newText = logs.toString(); + int lengthbefore = newText.length(); + if(lengthbefore >maxLogSizeTextLength){ + newText = truncateText(newText) + } // System.out.println("show text : ${newText}") // logsView.textArea.append(new) logsView.textArea.setText(newText); @@ -110,31 +145,20 @@ class RstaRunnerWithStackTrace2 extends RstaRunner { } } - - void showSTackTrace() { - Thread codeThread2 = codeThread - if (codeThread2 == null) { - log.info("thread value is null"); - } else { - List stackTraces = codeThread2.getStackTrace().toList(); - stackTraces = stackTraces.findAll { StackTraceElement el -> - String className = el.getClassName() - return ignoreClasses.find { className.startsWith(it) } == null - } - String text3 = stackTraces.join('\n'); - SwingUtilities.invokeLater { - textAreaStackTrace.textArea.text = text3 - } - } + String truncateText(String newText){ + logs = new StringBuffer() + totalLogSizeTruncated += maxLogSizeTextNewLength + logs.append("truncates old logs : ${totalLogSizeTruncated}\n") + newText= newText.substring(maxLogSizeTextNewLength) + logs.append(newText) + return newText } + + @Override - void codeStopped() { - super.codeStopped() - SwingUtilities.invokeLater { - textAreaStackTrace.textArea.text = "" - } - // Log4j2Utils.rootLogger.removeAppender(log4j2ThreadAppender) - showLogs() + protected void showStackTraceText(String stackTrace) { + textAreaStackTrace.textArea.text = stackTrace } + } \ No newline at end of file diff --git a/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace3.groovy b/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace3.groovy new file mode 100644 index 00000000..85168a6d --- /dev/null +++ b/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/RstaRunnerWithStackTrace3.groovy @@ -0,0 +1,155 @@ +package net.sf.jremoterun.utilities.nonjdk.rstarunner + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.idwutils.ViewAndPanel +import net.sf.jremoterun.utilities.nonjdk.log.Log4j2Utils +import net.sf.jremoterun.utilities.nonjdk.log.threadfilter.Log4j2ThreadAppender +import org.apache.logging.log4j.core.LogEvent + +import javax.swing.* +import java.awt.* +import java.util.List +import java.util.logging.Logger + +@CompileStatic +abstract class RstaRunnerWithStackTrace3 extends RstaRunner { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + +// StackTraceTextArea textAreaStackTrace = new StackTraceTextArea() + + List ignoreClasses = ['java.awt', 'javax.swing', 'groovy.lang.Closure.']; + + public ViewAndPanel runnerView = new ViewAndPanel("Runner", panel); + //public ViewAndPanel stackTraceView = new ViewAndPanel("Thread dump"); + //public TextAreaAndView logsView = new TextAreaAndView("Logs "); +// public TabWindow rightPanel +// public SplitWindow mainPanel4; + +// public volatile StringBuffer logs = new StringBuffer() + +// SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss") +// volatile int modCount = 0 + + Log4j2ThreadAppender log4j2ThreadAppender = new Log4j2ThreadAppender() { + @Override + void filterPassed(LogEvent loggingEvent) { + addLogEvent(loggingEvent) + } + } + + abstract void addLogEvent(LogEvent loggingEvent) + + +// SplitWindow getMainPanel3() { +// return mainPanel4; +// } + + + RstaRunnerWithStackTrace3(File file) { + super(file) + init3() + } + + RstaRunnerWithStackTrace3(String text2) { + super(text2) + init3() + } + + //abstract void doLoayout() +// rightPanel = new TabWindow() +// rightPanel.addTab(stackTraceView.view) +// rightPanel.addTab(logsView.view) +// doLayoutCreateMainPanel() +// } + +// void doLayoutCreateMainPanel() { +// mainPanel4 = new SplitWindow(true, 0.8f, runnerView.view, rightPanel) +// } + + protected void init3() { + //doLoayout() +// logsView.textArea.setEditable(false) +// logsView.textArea.setLineWrap(true) +// stackTraceView.panel.add(textAreaStackTrace.scrollPane, BorderLayout.CENTER) +// panel.add(textAreaStackTrace.scrollPane, BorderLayout.EAST) + log.info "scroll pane added" + ignoreClasses.addAll(JrrClassUtils.ignoreClassesForCurrentClass) + if (Log4j2Utils.rootLogger == null) { + log.info "root logger is null" + } else { + String appenderName = buildLogAppenderName() + log4j2ThreadAppender.setAppenderName(appenderName) + Log4j2Utils.rootLogger.addAppender(log4j2ThreadAppender) + } + log4j2ThreadAppender.translateAllLoggersForExecuterThread = true + } + + String buildLogAppenderName() { + String name2 = "RstaRunner-${getClass().getSimpleName()}-" + String name3 = name2 + new Random().nextInt() + Set set2 = Log4j2Utils.rootLogger.getAppenders().keySet(); + while (set2.contains(name2)) { + name3 = name2 + new Random().nextInt() + } + return name3 + } + +// @Override +// Component getMainPanel() { +// throw new IllegalStateException() +// } + + protected abstract void resetLogs() + + @Override + void codeStarted() { + super.codeStarted() + resetLogs() +// modCount = 0 +// analizedModCount = 0 + log4j2ThreadAppender.loggingThread = Thread.currentThread() + super.codeStarted() + } + + + @Override + void additionalHilighter() { + super.additionalHilighter() + showSTackTrace() + showLogs() + } + + protected void showSTackTrace() { + Thread codeThread2 = textAreaRunner.codeThread + if (codeThread2 == null) { + log.info("thread value is null"); + } else { + List stackTraces = codeThread2.getStackTrace().toList(); + stackTraces = stackTraces.findAll { StackTraceElement el -> + String className = el.getClassName() + return ignoreClasses.find { className.startsWith(it) } == null + } + String text3 = stackTraces.join('\n'); + SwingUtilities.invokeLater { + showStackTraceText(text3) + } + } + } + + protected abstract void showStackTraceText(String stackTrace); + + protected abstract void showLogs(); + + // t:dual + @Override + void codeStopped() { + super.codeStopped() + SwingUtilities.invokeLater { + showStackTraceText('') + } + // Log4j2Utils.rootLogger.removeAppender(log4j2ThreadAppender) + showLogs() + } +} \ No newline at end of file diff --git a/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/StopRequestIndicator.groovy b/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/StopRequestIndicator.groovy new file mode 100644 index 00000000..8660ca08 --- /dev/null +++ b/src-rsta-runner/net/sf/jremoterun/utilities/nonjdk/rstarunner/StopRequestIndicator.groovy @@ -0,0 +1,13 @@ +package net.sf.jremoterun.utilities.nonjdk.rstarunner + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class StopRequestIndicator { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static ThreadLocal stopRequest = new ThreadLocal<>() + +} diff --git a/src/timmoson/client/ClientParams.java b/src-timmoson/timmoson/client/ClientParams.java similarity index 81% rename from src/timmoson/client/ClientParams.java rename to src-timmoson/timmoson/client/ClientParams.java index e4e29e43..37151be8 100644 --- a/src/timmoson/client/ClientParams.java +++ b/src-timmoson/timmoson/client/ClientParams.java @@ -1,14 +1,13 @@ package timmoson.client; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.sertcp.TcpSession; public class ClientParams implements Cloneable{ - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public boolean retryIfIOException=true; public Boolean waitResult; diff --git a/src/timmoson/client/ClientSendRequest.java b/src-timmoson/timmoson/client/ClientSendRequest.java similarity index 98% rename from src/timmoson/client/ClientSendRequest.java rename to src-timmoson/timmoson/client/ClientSendRequest.java index 9491e5c7..d08ee535 100644 --- a/src/timmoson/client/ClientSendRequest.java +++ b/src-timmoson/timmoson/client/ClientSendRequest.java @@ -9,7 +9,6 @@ import net.sf.jremoterun.utilities.javassist.JavassistProxyFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.debug.TcpSessionNotifier; import timmoson.common.debug.TcpSessionTrackerBean; import timmoson.common.sertcp.Consts; @@ -31,10 +30,11 @@ import java.util.*; public class ClientSendRequest { - private static final Log log = LogFactory.getLog(Reflection.getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public static ThreadLocal clientParams = new ThreadLocal(); + public static long defaultWaitTime =10000; public static TcpSessionNotifier sessionNotifier; public static ClientParams getClientParams() { @@ -217,7 +217,7 @@ public Object makeCallNoThreadLocal(RequestInfoCleint infoClient) throws Excepti synchronized (infoClient.lock) { writeRequest(infoClient); while (true) { - infoClient.lock.wait(10000); + infoClient.lock.wait(defaultWaitTime); if (infoClient.tcpSession.isClosed()) { // requestInfoCleint.reponseBean = new ReponseBean(); throw new RuntimeException("Session is closed"); @@ -359,6 +359,7 @@ public void writeRequest(RequestInfoCleint requestInfoCleint, TcpSession session public void writeRequestInSyncBlock(RequestInfoCleint requestInfoCleint, byte[] paramsB, TcpSession session) throws Exception { + session.updateLastAccessWrite(); // session.outputStream.write(" ".getBytes()); session.outputStream.write(Consts.beginCallDesc.name().getBytes()); session.outputStream.write(paramsB); diff --git a/src/timmoson/client/ClientStaticUtils.java b/src-timmoson/timmoson/client/ClientStaticUtils.java similarity index 90% rename from src/timmoson/client/ClientStaticUtils.java rename to src-timmoson/timmoson/client/ClientStaticUtils.java index eb3ff3f7..57893a6b 100644 --- a/src/timmoson/client/ClientStaticUtils.java +++ b/src-timmoson/timmoson/client/ClientStaticUtils.java @@ -18,7 +18,8 @@ public static byte[] handleClientReponse(TcpSession tcpSession, ByteArrayOutputStream out, int i, String s) throws Exception { String s2 = s.substring(Consts.resultBegin.name().length() + 1, i - 1); log.debug(s2); - byte[][] bb23 =RemoteService. findBetween(Consts.resultBegin.name(), + tcpSession.updateLastAccessRead(); + byte[][] bb23 =RemoteService.defaultRemoteService. findBetween(Consts.resultBegin.name(), Consts.resultEnd.name(), tcpSession.inputStream, out); byte[] bb2 = bb23[0]; ReponseBean reponseBean = (ReponseBean) JrrUtils.deserialize(bb2, diff --git a/src/timmoson/client/DGCMonitor.java b/src-timmoson/timmoson/client/DGCMonitor.java similarity index 94% rename from src/timmoson/client/DGCMonitor.java rename to src-timmoson/timmoson/client/DGCMonitor.java index 2fcd91eb..8c661386 100644 --- a/src/timmoson/client/DGCMonitor.java +++ b/src-timmoson/timmoson/client/DGCMonitor.java @@ -1,8 +1,8 @@ package timmoson.client; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.sertcp.TcpSession; import timmoson.server.ServiceLocator; import timmoson.server.TcpServiceObject; @@ -17,8 +17,7 @@ import java.util.WeakHashMap; public class DGCMonitor { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public static WeakHashMap tcpSessions = new WeakHashMap(); private static boolean isRun = false; diff --git a/src/timmoson/client/ProxyCall.java b/src-timmoson/timmoson/client/ProxyCall.java similarity index 100% rename from src/timmoson/client/ProxyCall.java rename to src-timmoson/timmoson/client/ProxyCall.java diff --git a/src/timmoson/client/ProxyCallDiffClassloader.java b/src-timmoson/timmoson/client/ProxyCallDiffClassloader.java similarity index 100% rename from src/timmoson/client/ProxyCallDiffClassloader.java rename to src-timmoson/timmoson/client/ProxyCallDiffClassloader.java diff --git a/src/timmoson/client/ProxyCallInvocation.java b/src-timmoson/timmoson/client/ProxyCallInvocation.java similarity index 96% rename from src/timmoson/client/ProxyCallInvocation.java rename to src-timmoson/timmoson/client/ProxyCallInvocation.java index 11fe775a..3b31a5bf 100644 --- a/src/timmoson/client/ProxyCallInvocation.java +++ b/src-timmoson/timmoson/client/ProxyCallInvocation.java @@ -1,12 +1,12 @@ package timmoson.client; import junit.framework.Assert; +import net.sf.jremoterun.utilities.JrrClassUtils; import net.sf.jremoterun.utilities.javassist.BaseMethodHandler; import net.sf.jremoterun.utilities.javassist.InvokcationAccessor; import net.sf.jremoterun.utilities.javassist.JavassistProxyFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.transferedobjects.RemoteObjectServer; import timmoson.common.transferedobjects.ServiceId; import timmoson.server.TcpServiceObject; @@ -14,7 +14,7 @@ import java.lang.reflect.Method; public class ProxyCallInvocation extends BaseMethodHandler { - private static final Log log = LogFactory.getLog(Reflection.getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); final Class clazz; public TimmosonSessionStore tcpSession1; diff --git a/src/timmoson/client/RequestInfoCleint.java b/src-timmoson/timmoson/client/RequestInfoCleint.java similarity index 84% rename from src/timmoson/client/RequestInfoCleint.java rename to src-timmoson/timmoson/client/RequestInfoCleint.java index 9a407d6e..30f454e0 100644 --- a/src/timmoson/client/RequestInfoCleint.java +++ b/src-timmoson/timmoson/client/RequestInfoCleint.java @@ -3,13 +3,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.TcpCallCommon; import timmoson.common.transferedobjects.ReponseBean; public class RequestInfoCleint extends TcpCallCommon { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + //private static final Log log = LogFactory.getLog(Reflection + // .getCallerClass(1)); public volatile ClientParams clientParams; public volatile ClassLoader deserClassLoader; public volatile boolean firstCallInSession=true; diff --git a/src/timmoson/client/TcpSessionClosedListener.java b/src-timmoson/timmoson/client/TcpSessionClosedListener.java similarity index 100% rename from src/timmoson/client/TcpSessionClosedListener.java rename to src-timmoson/timmoson/client/TcpSessionClosedListener.java diff --git a/src/timmoson/client/TimmosonSessionStore.java b/src-timmoson/timmoson/client/TimmosonSessionStore.java similarity index 100% rename from src/timmoson/client/TimmosonSessionStore.java rename to src-timmoson/timmoson/client/TimmosonSessionStore.java diff --git a/src/timmoson/client/TimmosonSessionStoreAndBuilder.java b/src-timmoson/timmoson/client/TimmosonSessionStoreAndBuilder.java similarity index 91% rename from src/timmoson/client/TimmosonSessionStoreAndBuilder.java rename to src-timmoson/timmoson/client/TimmosonSessionStoreAndBuilder.java index c39b63d3..399a583c 100644 --- a/src/timmoson/client/TimmosonSessionStoreAndBuilder.java +++ b/src-timmoson/timmoson/client/TimmosonSessionStoreAndBuilder.java @@ -1,8 +1,8 @@ package timmoson.client; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.sertcp.RemoteService; import timmoson.common.sertcp.TcpSession; import timmoson.server.ServiceInfo; @@ -14,8 +14,7 @@ public class TimmosonSessionStoreAndBuilder implements TimmosonSessionStore { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public Object connectionLock = new Object(); public ServiceInfo serviceInfo; public String tcpHost; @@ -72,7 +71,7 @@ public void initTcpConnection() throws Exception { clienTcpSession.sessionBuilder = this; // clienTcpSession.sessionClosedListeners // .add(SessionCloseListenClient.sessionCloseListenClient); - RemoteService.handleSocketNewThread(clienTcpSession); + RemoteService.defaultRemoteService.handleSocketNewThread(clienTcpSession); } @Override diff --git a/src/timmoson/client/TimmosonSessionStoreSimple.java b/src-timmoson/timmoson/client/TimmosonSessionStoreSimple.java similarity index 100% rename from src/timmoson/client/TimmosonSessionStoreSimple.java rename to src-timmoson/timmoson/client/TimmosonSessionStoreSimple.java diff --git a/src/timmoson/client/telnet/TelnetTimmosonSessionStoreSimple.java b/src-timmoson/timmoson/client/telnet/TelnetTimmosonSessionStoreSimple.java similarity index 100% rename from src/timmoson/client/telnet/TelnetTimmosonSessionStoreSimple.java rename to src-timmoson/timmoson/client/telnet/TelnetTimmosonSessionStoreSimple.java diff --git a/src/timmoson/common/CallBackSession.java b/src-timmoson/timmoson/common/CallBackSession.java similarity index 77% rename from src/timmoson/common/CallBackSession.java rename to src-timmoson/timmoson/common/CallBackSession.java index 6bce1d4e..a9760221 100644 --- a/src/timmoson/common/CallBackSession.java +++ b/src-timmoson/timmoson/common/CallBackSession.java @@ -2,11 +2,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; public abstract class CallBackSession { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); +// private static final Log log = LogFactory.getLog(Reflection +// .getCallerClass(1)); public Object customProperties; diff --git a/src/timmoson/common/CallInfoServer.java b/src-timmoson/timmoson/common/CallInfoServer.java similarity index 100% rename from src/timmoson/common/CallInfoServer.java rename to src-timmoson/timmoson/common/CallInfoServer.java diff --git a/src/timmoson/common/ClientInfo.java b/src-timmoson/timmoson/common/ClientInfo.java similarity index 71% rename from src/timmoson/common/ClientInfo.java rename to src-timmoson/timmoson/common/ClientInfo.java index fc63f8f3..4e8dd0c7 100644 --- a/src/timmoson/common/ClientInfo.java +++ b/src-timmoson/timmoson/common/ClientInfo.java @@ -2,7 +2,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import java.io.Serializable; @@ -11,9 +10,7 @@ public class ClientInfo implements Serializable{ private static final long serialVersionUID = -5665470851988138362L; - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); - + public String userName; diff --git a/src/timmoson/common/TcpCallCommon.java b/src-timmoson/timmoson/common/TcpCallCommon.java similarity index 78% rename from src/timmoson/common/TcpCallCommon.java rename to src-timmoson/timmoson/common/TcpCallCommon.java index e3e5160a..91d10e3a 100644 --- a/src/timmoson/common/TcpCallCommon.java +++ b/src-timmoson/timmoson/common/TcpCallCommon.java @@ -3,16 +3,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.sertcp.TcpSession; import timmoson.common.transferedobjects.RequestBean; import java.lang.reflect.Method; public class TcpCallCommon { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); - public volatile TcpSession tcpSession; public volatile Object[] params; diff --git a/src/timmoson/common/debug/LocalSessionNotifier.java b/src-timmoson/timmoson/common/debug/LocalSessionNotifier.java similarity index 100% rename from src/timmoson/common/debug/LocalSessionNotifier.java rename to src-timmoson/timmoson/common/debug/LocalSessionNotifier.java diff --git a/src/timmoson/common/debug/LocalSessionRequestBean.java b/src-timmoson/timmoson/common/debug/LocalSessionRequestBean.java similarity index 82% rename from src/timmoson/common/debug/LocalSessionRequestBean.java rename to src-timmoson/timmoson/common/debug/LocalSessionRequestBean.java index ec9dc19c..701ff4f9 100644 --- a/src/timmoson/common/debug/LocalSessionRequestBean.java +++ b/src-timmoson/timmoson/common/debug/LocalSessionRequestBean.java @@ -3,16 +3,13 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.localcall.LocalSession; import java.lang.reflect.Method; import java.util.Date; public class LocalSessionRequestBean { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); - + public final Exception stackTrace=new Exception(); public Throwable exception; public final Date requestDate=new Date(); diff --git a/src/timmoson/common/debug/TcpSessionNotifier.java b/src-timmoson/timmoson/common/debug/TcpSessionNotifier.java similarity index 100% rename from src/timmoson/common/debug/TcpSessionNotifier.java rename to src-timmoson/timmoson/common/debug/TcpSessionNotifier.java diff --git a/src/timmoson/common/debug/TcpSessionTrackerBean.java b/src-timmoson/timmoson/common/debug/TcpSessionTrackerBean.java similarity index 87% rename from src/timmoson/common/debug/TcpSessionTrackerBean.java rename to src-timmoson/timmoson/common/debug/TcpSessionTrackerBean.java index 650951de..1847f19c 100644 --- a/src/timmoson/common/debug/TcpSessionTrackerBean.java +++ b/src-timmoson/timmoson/common/debug/TcpSessionTrackerBean.java @@ -3,7 +3,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.client.RequestInfoCleint; import timmoson.common.sertcp.TcpSession; import timmoson.server.TcpCallInfoServer; @@ -11,9 +10,7 @@ import java.util.Date; public class TcpSessionTrackerBean { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); - + public final Thread thread=Thread.currentThread(); // stored in infoCleint.requestBean.stackTrace // public Exception stackTrace; diff --git a/src/timmoson/common/remoterun/IfRegister.java b/src-timmoson/timmoson/common/remoterun/IfRegister.java similarity index 93% rename from src/timmoson/common/remoterun/IfRegister.java rename to src-timmoson/timmoson/common/remoterun/IfRegister.java index 051f3707..c62b7f10 100644 --- a/src/timmoson/common/remoterun/IfRegister.java +++ b/src-timmoson/timmoson/common/remoterun/IfRegister.java @@ -10,7 +10,6 @@ import net.sf.jremoterun.utilities.MBeanFromJavaBean; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.client.TimmosonSessionStoreSimple; import timmoson.common.sertcp.IfSharedObjects; import timmoson.common.sertcp.RemoteService; @@ -25,8 +24,6 @@ import java.util.Map; public class IfRegister implements ICodeForExecuting, DefaultObjectName { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); public static ObjectName objectName = JrrUtils .createObjectName("if:type=if"); @@ -66,7 +63,7 @@ public void connectToHost(String host, int port) throws Exception { // log.info("session closed " + new Date()); // } // }); - RemoteService.handleSocketNewThread(tcpSession); + RemoteService.defaultRemoteService.handleSocketNewThread(tcpSession); } @Override diff --git a/src/timmoson/common/remoterun/InvokactionRemoreRun.java b/src-timmoson/timmoson/common/remoterun/InvokactionRemoreRun.java similarity index 99% rename from src/timmoson/common/remoterun/InvokactionRemoreRun.java rename to src-timmoson/timmoson/common/remoterun/InvokactionRemoreRun.java index a3f6b283..5912f78a 100644 --- a/src/timmoson/common/remoterun/InvokactionRemoreRun.java +++ b/src-timmoson/timmoson/common/remoterun/InvokactionRemoreRun.java @@ -162,7 +162,7 @@ public void run() { // } else { // tcpSession.sessionBuilder = newSessionBuilderServer; // } - RemoteService.handleSocketNewThread(session); + RemoteService.defaultRemoteService.handleSocketNewThread(session); synchronized (lock) { lock.notify(); } diff --git a/src/timmoson/common/sertcp/Consts.java b/src-timmoson/timmoson/common/sertcp/Consts.java similarity index 100% rename from src/timmoson/common/sertcp/Consts.java rename to src-timmoson/timmoson/common/sertcp/Consts.java diff --git a/src/timmoson/common/sertcp/IfSharedObjects.java b/src-timmoson/timmoson/common/sertcp/IfSharedObjects.java similarity index 90% rename from src/timmoson/common/sertcp/IfSharedObjects.java rename to src-timmoson/timmoson/common/sertcp/IfSharedObjects.java index 4ad2e7ff..f10eeecb 100644 --- a/src/timmoson/common/sertcp/IfSharedObjects.java +++ b/src-timmoson/timmoson/common/sertcp/IfSharedObjects.java @@ -4,13 +4,10 @@ import net.sf.jremoterun.utilities.JrrUtilities; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import java.util.HashMap; public class IfSharedObjects { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); public static String IfSharedObjectsS = "timmoson.IfSharedObjects"; public static String callInfoS = "timmoson.callInfo"; diff --git a/src/timmoson/common/sertcp/MakeProxyDiffClassLoader.java b/src-timmoson/timmoson/common/sertcp/MakeProxyDiffClassLoader.java similarity index 97% rename from src/timmoson/common/sertcp/MakeProxyDiffClassLoader.java rename to src-timmoson/timmoson/common/sertcp/MakeProxyDiffClassLoader.java index a4bc2257..eecabb7b 100644 --- a/src/timmoson/common/sertcp/MakeProxyDiffClassLoader.java +++ b/src-timmoson/timmoson/common/sertcp/MakeProxyDiffClassLoader.java @@ -9,7 +9,6 @@ import net.sf.jremoterun.utilities.javassist.JavassistProxyFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.client.ProxyCallDiffClassloader; import java.io.IOException; @@ -18,7 +17,7 @@ import java.util.WeakHashMap; public class MakeProxyDiffClassLoader { - private static final Log log = LogFactory.getLog(Reflection.getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public static T makeClient(Class class1) throws Exception { return makeClient(class1, class1.getName()); diff --git a/src/timmoson/common/sertcp/ProxyCallInvocationDiffClassloader.java b/src-timmoson/timmoson/common/sertcp/ProxyCallInvocationDiffClassloader.java similarity index 92% rename from src/timmoson/common/sertcp/ProxyCallInvocationDiffClassloader.java rename to src-timmoson/timmoson/common/sertcp/ProxyCallInvocationDiffClassloader.java index 8d7f0237..1c53858d 100644 --- a/src/timmoson/common/sertcp/ProxyCallInvocationDiffClassloader.java +++ b/src-timmoson/timmoson/common/sertcp/ProxyCallInvocationDiffClassloader.java @@ -5,13 +5,12 @@ import net.sf.jremoterun.utilities.javassist.BaseMethodHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import java.lang.reflect.Method; import java.util.HashMap; public class ProxyCallInvocationDiffClassloader extends BaseMethodHandler { - private static final Log log = LogFactory.getLog(Reflection.getCallerClass(1)); + //private static final Log log = LogFactory.getLog(Reflection.getCallerClass(1)); public final Object object; diff --git a/src/timmoson/common/sertcp/RemoteService.java b/src-timmoson/timmoson/common/sertcp/RemoteService.java similarity index 88% rename from src/timmoson/common/sertcp/RemoteService.java rename to src-timmoson/timmoson/common/sertcp/RemoteService.java index 54000ff9..f5bae6f9 100644 --- a/src/timmoson/common/sertcp/RemoteService.java +++ b/src-timmoson/timmoson/common/sertcp/RemoteService.java @@ -1,8 +1,8 @@ package timmoson.common.sertcp; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.client.ClientSendRequest; import timmoson.client.ClientStaticUtils; import timmoson.client.DGCMonitor; @@ -13,8 +13,7 @@ import java.io.InputStream; public class RemoteService { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); // public static NewSessionBuilder newSessionBuilderServer=new // NewSessionBuilderSimple( @@ -23,6 +22,8 @@ public class RemoteService { public static boolean writeStrangeBytes = true; public static ThreadLocal callsInfos = IfSharedObjects.getCallInfo(); + public static RemoteService defaultRemoteService = new RemoteService(); + // public static TcpSocketLlistener socketLlistener = new // TcpSocketLlistener(); @@ -46,7 +47,7 @@ public class RemoteService { // } // } - public static void handleSocketNewThread(final TcpSession tcpSession) { + public void handleSocketNewThread(final TcpSession tcpSession) { Thread thread = new Thread("Socket " + tcpSession.socket.getRemoteSocketAddress()) { @Override @@ -85,6 +86,7 @@ private static void handleSocket(TcpSession tcpSession) throws Exception { // // private static void handleSocket2(TcpSession tcpSession) throws // Exception { + tcpSession.updateLastAccessRead(); final byte[] buffer = new byte[bufferSize]; ByteArrayOutputStream out = new ByteArrayOutputStream(); while (true) { @@ -131,7 +133,7 @@ private static ByteArrayOutputStream checkNext(ByteArrayOutputStream out, if(tcpSession.isClosed()) { return null; } - String s = new String(out.toByteArray(), "cp1251"); + String s = new String(out.toByteArray(), TimmosonSettings.defaultEncoding); // log.info(s); int i = s.indexOf(Consts.endCallDesc.name()); int k = s.indexOf(Consts.resultEnd.name()); @@ -157,7 +159,7 @@ public static int waitWord(InputStream in, ByteArrayOutputStream out, final byte[] buffer = new byte[bufferSize]; int readBytes; while (true) { - String s = new String(out.toByteArray(), "cp1251"); + String s = new String(out.toByteArray(), TimmosonSettings.defaultEncoding); log.debug(s); int i = s.indexOf(word); if (i != -1) { @@ -169,13 +171,13 @@ public static int waitWord(InputStream in, ByteArrayOutputStream out, // throw new Exception("end stream"); } - public static byte[][] findBetween(String begin, String end, + public byte[][] findBetween(String begin, String end, InputStream in, ByteArrayOutputStream out) throws Exception { int k = waitWord(in, out, end); byte[] bb = out.toByteArray(); - String dsfd = new String(bb, "cp1251"); + String dsfd = new String(bb, TimmosonSettings.defaultEncoding); log.debug(dsfd); int i = dsfd.indexOf(begin); if (i == -1) { @@ -188,7 +190,7 @@ public static byte[][] findBetween(String begin, String end, log.debug(beginI); log.debug(endI); - log.debug(new String(bb, beginI, diff + 1, "cp1251")); + log.debug(new String(bb, beginI, diff + 1, TimmosonSettings.defaultEncoding)); System.arraycopy(bb, beginI - 1, bb2, 0, bb2.length); log.debug(new String(bb2)); byte[][] bbbw = new byte[2][]; diff --git a/src/timmoson/common/sertcp/TcpSession.java b/src-timmoson/timmoson/common/sertcp/TcpSession.java similarity index 91% rename from src/timmoson/common/sertcp/TcpSession.java rename to src-timmoson/timmoson/common/sertcp/TcpSession.java index 45015b14..b86f5db7 100644 --- a/src/timmoson/common/sertcp/TcpSession.java +++ b/src-timmoson/timmoson/common/sertcp/TcpSession.java @@ -2,9 +2,9 @@ import junit.framework.Assert; import net.sf.jremoterun.JrrUtils; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.client.*; import timmoson.common.CallBackSession; import timmoson.common.transferedobjects.ReponseBean; @@ -28,8 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger; public class TcpSession extends CallBackSession { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public ArrayList sessionClosedListeners = new ArrayList(); public Map requets = new Hashtable(); @@ -44,6 +43,9 @@ public class TcpSession extends CallBackSession { */ public volatile int reqCount = 1; + public volatile long lastAccessRead; + public volatile long lastAccessWrite; + // public boolean sideId; /** @@ -61,6 +63,14 @@ public class TcpSession extends CallBackSession { private volatile static boolean initiedStatic = false; + public void updateLastAccessRead(){ + lastAccessRead = System.currentTimeMillis(); + } + + public void updateLastAccessWrite(){ + lastAccessWrite = System.currentTimeMillis(); + } + @Deprecated public TcpSession() { if (!initiedStatic) { @@ -165,7 +175,8 @@ public T makeClient(Class class1, String serviceId) { public static TcpSession buildTcpSession(Socket socket) throws IOException { TcpSession tcpSession = new TcpSession(); tcpSession.socket = socket; - + tcpSession.updateLastAccessRead(); + tcpSession.updateLastAccessWrite(); InputStream in = socket.getInputStream(); tcpSession.inputStream = in; tcpSession.outputStream = socket.getOutputStream(); diff --git a/src-timmoson/timmoson/common/sertcp/TimmosonSettings.groovy b/src-timmoson/timmoson/common/sertcp/TimmosonSettings.groovy new file mode 100644 index 00000000..7504fa40 --- /dev/null +++ b/src-timmoson/timmoson/common/sertcp/TimmosonSettings.groovy @@ -0,0 +1,16 @@ +package timmoson.common.sertcp + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.nio.charset.Charset; +import java.util.logging.Logger; + +@CompileStatic +class TimmosonSettings { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static Charset defaultEncoding = Charset.forName('cp1251') + + +} diff --git a/src/timmoson/common/telnet/TelnetRemoteService.java b/src-timmoson/timmoson/common/telnet/TelnetRemoteService.java similarity index 93% rename from src/timmoson/common/telnet/TelnetRemoteService.java rename to src-timmoson/timmoson/common/telnet/TelnetRemoteService.java index 37e3a3cf..514b1b09 100644 --- a/src/timmoson/common/telnet/TelnetRemoteService.java +++ b/src-timmoson/timmoson/common/telnet/TelnetRemoteService.java @@ -1,17 +1,17 @@ package timmoson.common.telnet; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.client.DGCMonitor; import timmoson.common.CallInfoServer; +import timmoson.common.sertcp.TimmosonSettings; import timmoson.server.telnet.TelnetServerUtilsStatic; import java.io.ByteArrayOutputStream; public class TelnetRemoteService { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); // public static NewSessionBuilder newSessionBuilderServer=new // NewSessionBuilderSimple( @@ -139,7 +139,7 @@ private static ByteArrayOutputStream checkNext(ByteArrayOutputStream out, // tcpSession.closeSession(); // return null; // } - String s = new String(asBytes, "cp1251"); + String s = new String(asBytes, TimmosonSettings.defaultEncoding); int end = s.indexOf('\r'); { int end2 = s.indexOf('\n'); @@ -169,7 +169,7 @@ private static ByteArrayOutputStream checkNext(ByteArrayOutputStream out, // if (type==TelnetConsts.i) { TelnetServerUtilsStatic.handleInvokation(tcpSession, thisInkoe); out = new ByteArrayOutputStream(); - out.write(otherInvoke.getBytes("cp1251")); + out.write(otherInvoke.getBytes(TimmosonSettings.defaultEncoding)); if (otherInvoke.length() == 0) { return out; } diff --git a/src/timmoson/common/telnet/TelnetSession.java b/src-timmoson/timmoson/common/telnet/TelnetSession.java similarity index 96% rename from src/timmoson/common/telnet/TelnetSession.java rename to src-timmoson/timmoson/common/telnet/TelnetSession.java index e247bf82..03a2ef69 100644 --- a/src/timmoson/common/telnet/TelnetSession.java +++ b/src-timmoson/timmoson/common/telnet/TelnetSession.java @@ -2,9 +2,9 @@ import junit.framework.Assert; import net.sf.jremoterun.JrrUtils; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.client.RequestInfoCleint; import timmoson.client.TcpSessionClosedListener; import timmoson.client.telnet.TelnetTimmosonSessionStoreSimple; @@ -22,8 +22,7 @@ //import timmoson.client.DGCMonitor; public class TelnetSession { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public ArrayList sessionClosedListeners = new ArrayList(); public Map requets = new Hashtable(); diff --git a/src/timmoson/common/transferedobjects/JmxServiceId.java b/src-timmoson/timmoson/common/transferedobjects/JmxServiceId.java similarity index 100% rename from src/timmoson/common/transferedobjects/JmxServiceId.java rename to src-timmoson/timmoson/common/transferedobjects/JmxServiceId.java diff --git a/src/timmoson/common/transferedobjects/RemoteObjectClient.java b/src-timmoson/timmoson/common/transferedobjects/RemoteObjectClient.java similarity index 77% rename from src/timmoson/common/transferedobjects/RemoteObjectClient.java rename to src-timmoson/timmoson/common/transferedobjects/RemoteObjectClient.java index ed2f4b87..b6dc8e52 100644 --- a/src/timmoson/common/transferedobjects/RemoteObjectClient.java +++ b/src-timmoson/timmoson/common/transferedobjects/RemoteObjectClient.java @@ -2,7 +2,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import java.io.Serializable; @@ -12,8 +11,6 @@ */ public class RemoteObjectClient implements Serializable{ private static final long serialVersionUID = 2664186260569165749L; - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); public ServiceId objectId; public String className; diff --git a/src/timmoson/common/transferedobjects/RemoteObjectServer.java b/src-timmoson/timmoson/common/transferedobjects/RemoteObjectServer.java similarity index 77% rename from src/timmoson/common/transferedobjects/RemoteObjectServer.java rename to src-timmoson/timmoson/common/transferedobjects/RemoteObjectServer.java index b6b37f96..9dcc6601 100644 --- a/src/timmoson/common/transferedobjects/RemoteObjectServer.java +++ b/src-timmoson/timmoson/common/transferedobjects/RemoteObjectServer.java @@ -2,7 +2,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import java.io.Serializable; @@ -12,8 +11,6 @@ */ public class RemoteObjectServer implements Serializable{ private static final long serialVersionUID = 2664186260569165749L; - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); public ServiceId objectId; // public boolean inSession; diff --git a/src/timmoson/common/transferedobjects/ReponseBean.java b/src-timmoson/timmoson/common/transferedobjects/ReponseBean.java similarity index 80% rename from src/timmoson/common/transferedobjects/ReponseBean.java rename to src-timmoson/timmoson/common/transferedobjects/ReponseBean.java index 78a87326..c28dbe65 100644 --- a/src/timmoson/common/transferedobjects/ReponseBean.java +++ b/src-timmoson/timmoson/common/transferedobjects/ReponseBean.java @@ -2,14 +2,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import java.io.Serializable; public class ReponseBean implements Serializable { private static final long serialVersionUID = 5493220940056404018L; - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); public String requestId; public byte[] response; public boolean resultNull=false; diff --git a/src/timmoson/common/transferedobjects/RequestBean.java b/src-timmoson/timmoson/common/transferedobjects/RequestBean.java similarity index 90% rename from src/timmoson/common/transferedobjects/RequestBean.java rename to src-timmoson/timmoson/common/transferedobjects/RequestBean.java index 3101f878..4ae510f6 100644 --- a/src/timmoson/common/transferedobjects/RequestBean.java +++ b/src-timmoson/timmoson/common/transferedobjects/RequestBean.java @@ -3,7 +3,6 @@ import net.sf.jremoterun.JrrUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import java.io.IOException; import java.io.Serializable; @@ -12,8 +11,7 @@ public class RequestBean implements Serializable { private static final long serialVersionUID = -7416210782302849223L; - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(RequestBean.class); public byte[] stackTrace; public boolean waitResult = true; diff --git a/src/timmoson/common/transferedobjects/ServiceId.java b/src-timmoson/timmoson/common/transferedobjects/ServiceId.java similarity index 100% rename from src/timmoson/common/transferedobjects/ServiceId.java rename to src-timmoson/timmoson/common/transferedobjects/ServiceId.java diff --git a/src/timmoson/common/transferedobjects/SessionServiceId.java b/src-timmoson/timmoson/common/transferedobjects/SessionServiceId.java similarity index 100% rename from src/timmoson/common/transferedobjects/SessionServiceId.java rename to src-timmoson/timmoson/common/transferedobjects/SessionServiceId.java diff --git a/src/timmoson/common/transferedobjects/StaticServiceId.java b/src-timmoson/timmoson/common/transferedobjects/StaticServiceId.java similarity index 100% rename from src/timmoson/common/transferedobjects/StaticServiceId.java rename to src-timmoson/timmoson/common/transferedobjects/StaticServiceId.java diff --git a/src/timmoson/localcall/CallInfoServerCallBack.java b/src-timmoson/timmoson/localcall/CallInfoServerCallBack.java similarity index 80% rename from src/timmoson/localcall/CallInfoServerCallBack.java rename to src-timmoson/timmoson/localcall/CallInfoServerCallBack.java index c1f1e4d3..67298ea6 100644 --- a/src/timmoson/localcall/CallInfoServerCallBack.java +++ b/src-timmoson/timmoson/localcall/CallInfoServerCallBack.java @@ -3,14 +3,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.CallBackSession; import timmoson.common.CallInfoServer; import timmoson.common.debug.LocalSessionNotifier; public class CallInfoServerCallBack implements CallInfoServer { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); public static LocalSessionNotifier localSessionNotifier; diff --git a/src/timmoson/localcall/LocalCallUtils.java b/src-timmoson/timmoson/localcall/LocalCallUtils.java similarity index 91% rename from src/timmoson/localcall/LocalCallUtils.java rename to src-timmoson/timmoson/localcall/LocalCallUtils.java index 848c54c8..59b03cac 100644 --- a/src/timmoson/localcall/LocalCallUtils.java +++ b/src-timmoson/timmoson/localcall/LocalCallUtils.java @@ -1,15 +1,15 @@ package timmoson.localcall; +import net.sf.jremoterun.utilities.JrrClassUtils; import net.sf.jremoterun.utilities.javaservice.CallProxyGeneralHandler; import net.sf.jremoterun.utilities.javassist.JavassistProxyFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.server.ServiceLocator; import timmoson.server.ServiceSupport; public class LocalCallUtils { - private static final Log log = LogFactory.getLog(Reflection.getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); // public static T makeProxy(final Class clazz) throws Exception { // // enhancer.setSuperclass(clazz); diff --git a/src/timmoson/localcall/LocalSession.java b/src-timmoson/timmoson/localcall/LocalSession.java similarity index 82% rename from src/timmoson/localcall/LocalSession.java rename to src-timmoson/timmoson/localcall/LocalSession.java index 8336dd30..bb7682af 100644 --- a/src/timmoson/localcall/LocalSession.java +++ b/src-timmoson/timmoson/localcall/LocalSession.java @@ -3,12 +3,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.CallBackSession; public class LocalSession extends CallBackSession { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); @Override public T makeClient(Class class1, String serviceId) throws Exception { diff --git a/src/timmoson/server/GetReponseHandler.java b/src-timmoson/timmoson/server/GetReponseHandler.java similarity index 100% rename from src/timmoson/server/GetReponseHandler.java rename to src-timmoson/timmoson/server/GetReponseHandler.java diff --git a/src/timmoson/server/ServerUtilsStatic.java b/src-timmoson/timmoson/server/ServerUtilsStatic.java similarity index 97% rename from src/timmoson/server/ServerUtilsStatic.java rename to src-timmoson/timmoson/server/ServerUtilsStatic.java index 0f8147c5..80d2feb0 100644 --- a/src/timmoson/server/ServerUtilsStatic.java +++ b/src-timmoson/timmoson/server/ServerUtilsStatic.java @@ -65,7 +65,8 @@ public static byte[] handleInvokation(TcpSession tcpSession, // int parsmNumber = Integer.parseInt(properties // .getProperty(Consts.paramsNumber.name())); // Object serviceId = properties.getProperty(Consts.serviceId.name()); - byte[][] bb23 = RemoteService.findBetween(Consts.beginCallDesc.name(), + tcpSession.updateLastAccessRead(); + byte[][] bb23 = RemoteService.defaultRemoteService.findBetween(Consts.beginCallDesc.name(), Consts.endCallDesc.name(), tcpSession.inputStream, out); byte[] bb2 = bb23[0]; RequestBean requestBean = (RequestBean) JrrUtils.deserialize(bb2, @@ -169,6 +170,7 @@ public static void writeResponse(ReponseBean reponseBean, TcpSession tcpSession) throws IOException { byte[] res = JrrUtils.serialize(reponseBean); try { + tcpSession.updateLastAccessWrite(); synchronized (tcpSession.sendLock) { tcpSession.outputStream.write(Consts.resultBegin.name() .getBytes()); diff --git a/src/timmoson/server/ServiceCallServerInvoker.java b/src-timmoson/timmoson/server/ServiceCallServerInvoker.java similarity index 97% rename from src/timmoson/server/ServiceCallServerInvoker.java rename to src-timmoson/timmoson/server/ServiceCallServerInvoker.java index 6262632f..660026e0 100644 --- a/src/timmoson/server/ServiceCallServerInvoker.java +++ b/src-timmoson/timmoson/server/ServiceCallServerInvoker.java @@ -1,9 +1,9 @@ package timmoson.server; import net.sf.jremoterun.JrrUtils; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.client.ClientSendRequest; import timmoson.common.debug.TcpSessionTrackerBean; import timmoson.common.sertcp.RemoteService; @@ -18,8 +18,7 @@ import java.util.Date; public class ServiceCallServerInvoker { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); // public static ServiceCallServerInvoker serviceCallServerInvoker = new // ServiceCallServerInvoker(); diff --git a/src/timmoson/server/ServiceCallServerInvokerDebug.java b/src-timmoson/timmoson/server/ServiceCallServerInvokerDebug.java similarity index 95% rename from src/timmoson/server/ServiceCallServerInvokerDebug.java rename to src-timmoson/timmoson/server/ServiceCallServerInvokerDebug.java index 9c50fa72..6fa257f1 100644 --- a/src/timmoson/server/ServiceCallServerInvokerDebug.java +++ b/src-timmoson/timmoson/server/ServiceCallServerInvokerDebug.java @@ -2,10 +2,10 @@ import net.sf.jremoterun.JrrUtils; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.commonutils.CommonToString2; -import sun.reflect.Reflection; import timmoson.common.sertcp.TcpSession; import timmoson.common.transferedobjects.ReponseBean; @@ -15,8 +15,7 @@ public abstract class ServiceCallServerInvokerDebug extends ServiceCallServerInvoker { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public boolean doLog = true; diff --git a/src/timmoson/server/ServiceCallServerInvokerDebugFile.java b/src-timmoson/timmoson/server/ServiceCallServerInvokerDebugFile.java similarity index 90% rename from src/timmoson/server/ServiceCallServerInvokerDebugFile.java rename to src-timmoson/timmoson/server/ServiceCallServerInvokerDebugFile.java index 9f60bc82..520153a3 100644 --- a/src/timmoson/server/ServiceCallServerInvokerDebugFile.java +++ b/src-timmoson/timmoson/server/ServiceCallServerInvokerDebugFile.java @@ -4,16 +4,14 @@ import net.sf.jremoterun.utilities.FileOutputStream2; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.sertcp.TcpSession; +import timmoson.common.sertcp.TimmosonSettings; import java.io.File; import java.io.IOException; public abstract class ServiceCallServerInvokerDebugFile extends ServiceCallServerInvokerDebug { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); public boolean doLog = true; @@ -49,7 +47,8 @@ public void writeLog(StringBuffer sb) throws IOException { Assert.assertNotNull(fileOut); String msg = sb.toString(); Assert.assertNotNull(msg); - fileOut.write(msg.getBytes("cp1251")); + byte[] bytes = msg.getBytes(TimmosonSettings.defaultEncoding); + fileOut.write(bytes); } } diff --git a/src/timmoson/server/ServiceInfo.java b/src-timmoson/timmoson/server/ServiceInfo.java similarity index 80% rename from src/timmoson/server/ServiceInfo.java rename to src-timmoson/timmoson/server/ServiceInfo.java index c2124de2..f86411f7 100644 --- a/src/timmoson/server/ServiceInfo.java +++ b/src-timmoson/timmoson/server/ServiceInfo.java @@ -2,11 +2,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; public class ServiceInfo extends ServiceSupport{ - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); public String serviceId; diff --git a/src/timmoson/server/ServiceLocator.groovy b/src-timmoson/timmoson/server/ServiceLocator.groovy similarity index 88% rename from src/timmoson/server/ServiceLocator.groovy rename to src-timmoson/timmoson/server/ServiceLocator.groovy index 6a01f6b1..b4228891 100644 --- a/src/timmoson/server/ServiceLocator.groovy +++ b/src-timmoson/timmoson/server/ServiceLocator.groovy @@ -4,13 +4,11 @@ import groovy.transform.CompileStatic; import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.misc.VM; -import sun.reflect.Reflection; import timmoson.common.sertcp.IfSharedObjects; @CompileStatic public class ServiceLocator { - private static final Log log = LogFactory.getLog(Reflection.getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public static ServiceSupport getService(Class clazz) throws Exception { ServiceSupport service = getService(clazz.getName()); @@ -82,9 +80,4 @@ public class ServiceLocator { } } - public static void allowArrayClassloader() throws Exception { - JrrClassUtils.setFieldValue(VM.class, "allowArraySyntax", true); - JrrClassUtils.setFieldValue(VM.class, "defaultAllowArraySyntax", true); - } - } diff --git a/src/timmoson/server/ServiceSupport.groovy b/src-timmoson/timmoson/server/ServiceSupport.groovy similarity index 100% rename from src/timmoson/server/ServiceSupport.groovy rename to src-timmoson/timmoson/server/ServiceSupport.groovy diff --git a/src/timmoson/server/TcpCallInfoServer.java b/src-timmoson/timmoson/server/TcpCallInfoServer.java similarity index 84% rename from src/timmoson/server/TcpCallInfoServer.java rename to src-timmoson/timmoson/server/TcpCallInfoServer.java index d229718b..fbcf98d2 100644 --- a/src/timmoson/server/TcpCallInfoServer.java +++ b/src-timmoson/timmoson/server/TcpCallInfoServer.java @@ -3,14 +3,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.CallBackSession; import timmoson.common.CallInfoServer; import timmoson.common.TcpCallCommon; public class TcpCallInfoServer extends TcpCallCommon implements CallInfoServer { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); // remove recently // public volatile Method method; diff --git a/src/timmoson/server/TcpServiceObject.java b/src-timmoson/timmoson/server/TcpServiceObject.java similarity index 75% rename from src/timmoson/server/TcpServiceObject.java rename to src-timmoson/timmoson/server/TcpServiceObject.java index 45fbcd0e..34a2ff8f 100644 --- a/src/timmoson/server/TcpServiceObject.java +++ b/src-timmoson/timmoson/server/TcpServiceObject.java @@ -3,14 +3,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.transferedobjects.ServiceId; import java.util.Date; public class TcpServiceObject extends ServiceSupport{ - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); public final Date createDate=new Date(); public Date lastAccess=createDate; public ServiceId serviceInSessionId; diff --git a/src/timmoson/server/TcpSocketLlistener.java b/src-timmoson/timmoson/server/TcpSocketLlistener.java similarity index 94% rename from src/timmoson/server/TcpSocketLlistener.java rename to src-timmoson/timmoson/server/TcpSocketLlistener.java index 29136821..b9af55d8 100644 --- a/src/timmoson/server/TcpSocketLlistener.java +++ b/src-timmoson/timmoson/server/TcpSocketLlistener.java @@ -65,7 +65,7 @@ public void startListener() throws IOException { // } else { // tcpSession.sessionBuilder = newSessionBuilderServer; // } - RemoteService.handleSocketNewThread(tcpSession); + RemoteService.defaultRemoteService.handleSocketNewThread(tcpSession); } } @@ -77,7 +77,7 @@ public void stop() throws IOException { } public void handleSocketNewThread(TcpSession tcpSession) { - RemoteService.handleSocketNewThread(tcpSession); + RemoteService.defaultRemoteService.handleSocketNewThread(tcpSession); } public Thread startListenerInNewThread() throws IOException { diff --git a/src/timmoson/server/service/DefaultService.java b/src-timmoson/timmoson/server/service/DefaultService.java similarity index 100% rename from src/timmoson/server/service/DefaultService.java rename to src-timmoson/timmoson/server/service/DefaultService.java diff --git a/src/timmoson/server/service/TcpService.java b/src-timmoson/timmoson/server/service/TcpService.java similarity index 88% rename from src/timmoson/server/service/TcpService.java rename to src-timmoson/timmoson/server/service/TcpService.java index 49a6ab23..4c2e0685 100644 --- a/src/timmoson/server/service/TcpService.java +++ b/src-timmoson/timmoson/server/service/TcpService.java @@ -1,9 +1,9 @@ package timmoson.server.service; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.client.ClientSendRequest; import timmoson.common.CallInfoServer; import timmoson.common.sertcp.RemoteService; @@ -16,8 +16,7 @@ public class TcpService { // set ClientSendRequest.getClientParams().overrideTcpSession before invokaction public static TcpService tcpServiceRemote=ClientSendRequest.makeProxy(TcpService.class,null,serviceId); - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public void removeLocalSessionObject(String objectId) { CallInfoServer callInfoServer=RemoteService.callsInfos.get(); diff --git a/src/timmoson/server/service/TestService.java b/src-timmoson/timmoson/server/service/TestService.java similarity index 100% rename from src/timmoson/server/service/TestService.java rename to src-timmoson/timmoson/server/service/TestService.java diff --git a/src/timmoson/server/telnet/TelnetRequestBean.java b/src-timmoson/timmoson/server/telnet/TelnetRequestBean.java similarity index 76% rename from src/timmoson/server/telnet/TelnetRequestBean.java rename to src-timmoson/timmoson/server/telnet/TelnetRequestBean.java index 9eeca8ca..dc22a309 100644 --- a/src/timmoson/server/telnet/TelnetRequestBean.java +++ b/src-timmoson/timmoson/server/telnet/TelnetRequestBean.java @@ -2,7 +2,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.telnet.TelnetSession; import timmoson.server.ServiceSupport; @@ -11,9 +10,7 @@ public class TelnetRequestBean { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); - public ServiceSupport seriveObject; + public ServiceSupport seriveObject; public String serviceId; public String methodName; public ArrayList params=new ArrayList(); diff --git a/src/timmoson/server/telnet/TelnetServerUtilsStatic.java b/src-timmoson/timmoson/server/telnet/TelnetServerUtilsStatic.java similarity index 97% rename from src/timmoson/server/telnet/TelnetServerUtilsStatic.java rename to src-timmoson/timmoson/server/telnet/TelnetServerUtilsStatic.java index 09af4618..5bf47421 100644 --- a/src/timmoson/server/telnet/TelnetServerUtilsStatic.java +++ b/src-timmoson/timmoson/server/telnet/TelnetServerUtilsStatic.java @@ -3,6 +3,7 @@ import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.log4j.Logger; import org.commonutils.CommonToString2; +import timmoson.common.sertcp.TimmosonSettings; import timmoson.common.telnet.TelnetSession; import timmoson.server.ServerUtilsStatic; import timmoson.server.ServiceLocator; @@ -125,7 +126,7 @@ public static void writeResponse(Object reponse, TelnetSession tcpSession) sb.append(reponse); sb.append(sep); synchronized (tcpSession.sendLock) { - tcpSession.outputStream.write(sb.toString().getBytes("cp1251")); + tcpSession.outputStream.write(sb.toString().getBytes(TimmosonSettings.defaultEncoding)); tcpSession.outputStream.flush(); } } catch (IOException e) { diff --git a/src/timmoson/server/telnet/TelnetSocketLlistener.java b/src-timmoson/timmoson/server/telnet/TelnetSocketLlistener.java similarity index 100% rename from src/timmoson/server/telnet/TelnetSocketLlistener.java rename to src-timmoson/timmoson/server/telnet/TelnetSocketLlistener.java diff --git a/src/timmoson/testservice/CallbackService.java b/src-timmoson/timmoson/testservice/CallbackService.java similarity index 64% rename from src/timmoson/testservice/CallbackService.java rename to src-timmoson/timmoson/testservice/CallbackService.java index 73db98e6..e0f0b7c7 100644 --- a/src/timmoson/testservice/CallbackService.java +++ b/src-timmoson/timmoson/testservice/CallbackService.java @@ -3,12 +3,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; public class CallbackService { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(CallbackService.class); public void callback() { log.info("callback ok"); diff --git a/src/timmoson/testservice/SampleService.java b/src-timmoson/timmoson/testservice/SampleService.java similarity index 89% rename from src/timmoson/testservice/SampleService.java rename to src-timmoson/timmoson/testservice/SampleService.java index 0661bd92..ebb435bf 100644 --- a/src/timmoson/testservice/SampleService.java +++ b/src-timmoson/timmoson/testservice/SampleService.java @@ -1,14 +1,13 @@ package timmoson.testservice; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.common.sertcp.MakeProxyDiffClassLoader; import timmoson.common.sertcp.RemoteService; public class SampleService { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public static String strResturn = "7ffd723"; diff --git a/src/net/sf/jremoterun/utilities/nonjdk/AppRunner.groovy b/src/net/sf/jremoterun/utilities/nonjdk/AppRunner.groovy index 4fac2cd0..eb06edec 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/AppRunner.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/AppRunner.groovy @@ -20,6 +20,9 @@ abstract class AppRunner { abstract void runProcesses(); + /** + * Delay in ms + */ public long sleepTime = 600_000; void askToRunNewThread() throws Exception { @@ -27,12 +30,16 @@ abstract class AppRunner { try { askToRun() } catch (Throwable e) { - JrrUtilities.showException("Failed run ${taskGroupName}", e); + onException(e) } } new Thread(r, "${taskGroupName}").start() } + void onException(Throwable e){ + JrrUtilities.showException("Failed run ${taskGroupName}", e); + } + void askToRun() throws Exception { Date startDate = new Date() final ObjectWrapper continueFlag = new ObjectWrapper(true); diff --git a/src/net/sf/jremoterun/utilities/nonjdk/InitGeneral.groovy b/src/net/sf/jremoterun/utilities/nonjdk/InitGeneral.groovy index 75574c4e..9d0e780d 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/InitGeneral.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/InitGeneral.groovy @@ -1,20 +1,29 @@ package net.sf.jremoterun.utilities.nonjdk import groovy.transform.CompileStatic +import net.infonode.properties.propertymap.JrrIdwPropertyMapManager import net.sf.jremoterun.JrrUtils import net.sf.jremoterun.SharedObjectsUtils import net.sf.jremoterun.SimpleFindParentClassLoader +import net.sf.jremoterun.SimpleJvmTiAgent import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.MavenDependenciesResolver import net.sf.jremoterun.utilities.groovystarter.runners.RunnableFactory +import net.sf.jremoterun.utilities.java11.Java11ModuleSetDisable import net.sf.jremoterun.utilities.log4j.Log4jConfigurator import net.sf.jremoterun.utilities.mdep.ivy.IvyDepResolver2 import net.sf.jremoterun.utilities.nonjdk.classpath.CheckNonCache2 +import net.sf.jremoterun.utilities.nonjdk.classpath.inittracker.InitLogTracker +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs +import net.sf.jremoterun.utilities.nonjdk.compile.auxh.AddGroovyToParentClResolver import net.sf.jremoterun.utilities.nonjdk.consoleprograms.SetConsoleColoring +import net.sf.jremoterun.utilities.nonjdk.ivy.JrrDependecyAmenderDefault import net.sf.jremoterun.utilities.nonjdk.javassist.LoggigingRedefine +import net.sf.jremoterun.utilities.nonjdk.log.AddDefaultIgnoreClasses import net.sf.jremoterun.utilities.nonjdk.log.JdkLog2Log4jInit import net.sf.jremoterun.utilities.nonjdk.log.Log4j1Utils import net.sf.jremoterun.utilities.nonjdk.log.Log4j2Utils @@ -37,15 +46,19 @@ class InitGeneral { public static volatile boolean useColorOutput = true; public static volatile ClRef helfyInit = new ClRef('net.sf.jremoterun.utilities.nonjdk.helfyutils.HelpfyRegister') public static volatile ClRef helfyCore = new ClRef('one.helfy.JVM') + public static volatile InitGeneral initGeneral1 = new InitGeneral(); static void init1() { if (!inited && !inInit) { try { + InitLogTracker.defaultTracker.addLog("start init at ${new Date()}"); inInit = true; - init1impl() - } catch (Exception e) { + initGeneral1.init1impl() + InitLogTracker.defaultTracker.addLog("finished init at ${new Date()}"); + } catch (Throwable e) { +// JrrUtilities.showException("failed init", e) + InitLogTracker.defaultTracker.addException("failed init",e); log.info("${e}"); - JrrUtilities.showException("failed init", e) throw e; } finally { inInit = false; @@ -55,14 +68,18 @@ class InitGeneral { } static void checkJavassistClassloaderCorrectly() { - String className = javassist.runtime.Desc.name + String className = javassist.runtime.Desc.getName() ClassLoader javassistClassLoader = JrrClassUtils.currentClassLoader.loadClass(className).classLoader if (javassistClassLoader != null) { JrrUtilities.showException("javassist ClassLoader", new Exception("Class ${className} loaded by not boot classloader : ${javassistClassLoader}")) } } - static void init1impl() { + void init1impl() { + firstAction(); + InitLogTracker.defaultTracker.addLog("initing coloring") + Java11ModuleSetDisable.doIfNeeded(); + InitLogTracker.defaultTracker.addLog("java11 module check disabled") if (useColorOutput) { SetConsoleColoring.installAnsible() } @@ -70,32 +87,40 @@ class InitGeneral { checkJavassistClassloaderCorrectly(); } // ProxySelectorLogger.setProxySelectorWithJustLogging(); - JrrClassUtils.ignoreClassesForCurrentClass.add(Log4j1Utils.getPackage().getName()); + AddDefaultIgnoreClasses.addIgnoreClasses() +// JrrClassUtils.ignoreClassesForCurrentClass.add(Log4j1Utils.getPackage().getName()); SettingsChecker.showAsSwing = true + InitLogTracker.defaultTracker.addLog("setting log4j configurator") try { Log4jConfigurator.registerLog4jConfiguratorAndMbeans() } catch (Exception e) { + InitLogTracker.defaultTracker.addException("failed log4j mbean register",e) Throwable e2 = JrrUtils.getRootException(e); - if (e2 instanceof ClassNotFoundException && e2.message == 'org.apache.log4j.jmx.HierarchyDynamicMBean') { + if (e2 instanceof ClassNotFoundException && e2.getMessage() == 'org.apache.log4j.jmx.HierarchyDynamicMBean') { } else { log.log(Level.WARNING, "failed regiter log4j", e2) } } - Log4j1Utils.setLog4jAppender() - Log4j2Utils.setLog4jAppender() - JdkLog2Log4jInit.jdk2log4j(); - CheckNonCache2.check(); - CheckNonCache2.check(JrrUtilities); - - LoggigingRedefine.redifineLoggingGetLog(); + InitLogTracker.defaultTracker.addLog("setting logging") + setLogging() + InitLogTracker.defaultTracker.addLog("exception handler setting"); SimpleUncaughtExceptionHandler.setDefaultUncaughtExceptionHandler() - GeneralUtils.startLogTimer() + if (!SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9)) { + if(SimpleJvmTiAgent.instrumentation != null) { + net.sf.jremoterun.utilities.nonjdk.serviceloader.ServiceLoaderStorage.init() + } + } int pid = PidDetector.detectPid(); log.info "pid = ${pid}" // if (MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver == null) { - IvyDepResolver2.setDepResolver() + InitLogTracker.defaultTracker.addLog("setting resolver"); + JrrDependecyAmenderDefault.setResolverAmender(); + net.sf.jremoterun.utilities.nonjdk.ivy.ManyReposDownloaderImpl.setManyRepoLoader(); + net.sf.jremoterun.utilities.nonjdk.ivy.JrrIvyURLHandler.setHandler() + //IvyDepResolver2.setDepResolver() // } - SourceCompletionProvider.loadPrivateMemberAlways = true + //SourceCompletionProvider.loadPrivateMemberAlways = true + InitLogTracker.defaultTracker.addLog("setting default classloader for remote code execution"); SharedObjectsUtils.getClassLoaders().put(JrrUtilitiesSettings.generalInitCLassLoaderId, InitGeneral.classLoader); if (SimpleFindParentClassLoader.getDefaultClassLoader() == ClassLoader.getSystemClassLoader()) { SimpleFindParentClassLoader.setDefaultClassLoader(InitGeneral.classLoader) @@ -109,9 +134,46 @@ class InitGeneral { log.info("failed load class ${helfyCore} ${e}") } } + afterDependencySet() + initifFrameworkDir() + InitLogTracker.defaultTracker.addLog("init general done fine"); + lastAction() + } + + void initifFrameworkDir(){ + if(InfocationFrameworkStructure.ifDir == null) { + InfocationFrameworkStructure.ifDir = GitSomeRefs.ifFramework.resolveToFile() + } + } + + void firstAction(){ + + } + + void setLogging(){ + InitLogTracker.defaultTracker.addLog("setting log4j2 appender") + Log4j2Utils.setLog4jAppender() + InitLogTracker.defaultTracker.addLog("setting log4j1 appender") + Log4j1Utils.setLog4jAppender() + InitLogTracker.defaultTracker.addLog("setting jdk log appender") + JdkLog2Log4jInit.jdk2log4j(); + CheckNonCache2.check(); + CheckNonCache2.check(JrrUtilities); + + LoggigingRedefine.redifineLoggingGetLog(); + GeneralUtils.startLogTimer() + InitLogTracker.defaultTracker.addLog("logging set fine"); + } + + void afterDependencySet(){ + AddGroovyToParentClResolver.setRef(); + } + + void lastAction(){ + } - static void checkMavenUrlInDepResolver() { + void checkMavenUrlInDepResolver() { MavenDefaultSettings mds = MavenDefaultSettings.mavenDefaultSettings; MavenDependenciesResolver resolver = mds.mavenDependenciesResolver; if (resolver == null) { diff --git a/src/net/sf/jremoterun/utilities/nonjdk/JavaProcessRunner.groovy b/src/net/sf/jremoterun/utilities/nonjdk/JavaProcessRunner.groovy index 5332e70d..f362a2f0 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/JavaProcessRunner.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/JavaProcessRunner.groovy @@ -3,35 +3,42 @@ package net.sf.jremoterun.utilities.nonjdk import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.groovystarter.JrrStarterConstatnts import net.sf.jremoterun.utilities.groovystarter.runners.ClRefRef import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.AddFileToClassloaderDummy import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs2 import org.apache.commons.lang3.SystemUtils import java.util.logging.Logger +//TODO add debug option like : -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:1166,suspend=y,server=n @CompileStatic class JavaProcessRunner { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - public static String javaBinaryDefault = 'java' - public static List javaArgsDefault = [] - public static List javaClasspathDefault = [] - public static ClRef groovyMainRunner = new ClRef(groovy.ui.GroovyMain) + public static final int javaUsed = 2; + public static final int javawUsed = 3; + public static String javaBinaryDefault = 'java'; + public static List javaArgsDefault = []; + public static List javaClasspathDefault = []; + public static ClRef groovyMainRunner = new ClRef(groovy.ui.GroovyMain); - Properties javaProps = new Properties() - String javaBinary = javaBinaryDefault - List javaArgs = javaArgsDefault - List javaMainArgs = [] - ClRefRef mainClass + Properties javaProps = new Properties(); + String javaBinary = javaBinaryDefault; + List javaArgs = javaArgsDefault; + List javaMainArgs = []; + int xMxInMg = -1; + ClRefRef mainClass; List fullCmd = [] File runDir; List env = []; - Process process - int exitCode - Date startTime + Process process; + int exitCode; + Date startTime; AddFileToClassloaderDummy javaClasspath = new AddFileToClassloaderDummy(); @@ -39,9 +46,9 @@ class JavaProcessRunner { init() } - void init(){ + void init() { javaClasspath.isLogFileAlreadyAdded = false - if(javaClasspathDefault.size()>0) { + if (javaClasspathDefault.size() > 0) { javaClasspath.addAll javaClasspathDefault } File javaExec = org.apache.commons.lang3.SystemUtils.getJavaHome().child('bin/java') @@ -51,6 +58,13 @@ class JavaProcessRunner { void buildCmd() { fullCmd.add javaBinary fullCmd.addAll javaArgs + if (xMxInMg > 0) { + String xmxAlreadyAdded = javaArgs.find { it.startsWith('-Xmx') } + if (xmxAlreadyAdded != null) { + throw new Exception("-Xmx was added in another way : ${xmxAlreadyAdded} ") + } + fullCmd.add("-Xmx${xMxInMg}m".toString()) + } fullCmd.addAll javaProps.collect { "-D${it.key}=${it.value}".toString() } if (javaClasspath.addedFiles2.size() > 0) { fullCmd.add '-classpath' @@ -62,29 +76,57 @@ class JavaProcessRunner { } + void setHeapDumpPath(File pathToHeapDump){ + File parentFile = pathToHeapDump.getParentFile() + if(!parentFile.exists()){ + throw new FileNotFoundException("heap dump parent path not found : ${parentFile}") + } + javaArgs.add "-XX:HeapDumpPath=${pathToHeapDump.getAbsolutePath()}".toString() + } + + void addJmxOpts() { + javaProps.setProperty('com.sun.management.jmxremote', 'true') + javaProps.setProperty('com.sun.management.jmxremote.ssl', 'false') + javaProps.setProperty('com.sun.management.jmxremote.authenticate', 'false') + } + + void setJrrConfig2Dir(File dir) { + assert dir.exists() + javaProps.setProperty(JrrStarterConstatnts.jrrConfig2DirSystemProperty, dir.getAbsolutePath()) + } + + + void addJmxOpts2(int port) { + javaProps.setProperty('com.sun.management.jmxremote.port', "${port}") + addJmxOpts() + } + void setJrrRunner2(int type) { - if(SystemUtils.IS_OS_WINDOWS){ - if(type in [2,3]){ + if (SystemUtils.IS_OS_WINDOWS) { + if (type in [javaUsed, javawUsed]) { - }else{ + } else { throw new IllegalStateException("Invalid type : ${type}, allowed : 2 or 3") } - }else{ - type = 2 + } else { + type = javaUsed } - File jrrStarterLibsDir = GitReferences.groovyClasspathDir.resolveToFile() - setJrrRunner(type, jrrStarterLibsDir) + File jrrStarterLibsDir = JrrStarterJarRefs.groovyClasspathDir.resolveToFile() + setJrrRunner(type, jrrStarterLibsDir, JrrStarterJarRefs.groovyRunner.resolveToFile()) } - void setJrrRunner(int type, File jrrStarterLibsDir) { - File jrrFile = jrrStarterLibsDir.child('jremoterun.jar') + void setJrrRunner(int runnerType, File jrrStarterLibsDir, File groovyRunnerScript) { + // for runnerType see + new ClRef('net.sf.jremoterun.utilities.init.commonrunner.JrrRunnerProperties') + assert groovyRunnerScript.isFile() + File jrrFile = jrrStarterLibsDir.child(JrrStarterJarRefs2.jremoterun.getJarName()) assert jrrFile.exists() javaArgs.add "-javaagent:${jrrFile.absolutePath}".toString() - javaClasspath.addF jrrStarterLibsDir.child('groovy_custom.jar') - javaClasspath.addF jrrStarterLibsDir.child('groovy.jar') + javaClasspath.addF jrrStarterLibsDir.child(JrrStarterJarRefs2.groovy_custom.getJarName()) + javaClasspath.addF jrrStarterLibsDir.child(JrrStarterJarRefs2.groovy.getJarName()) mainClass = groovyMainRunner - javaMainArgs.add(0, GitReferences.groovyRunner.resolveToFile().absolutePath) - javaMainArgs.add(1, type as String) + javaMainArgs.add(0, groovyRunnerScript.absolutePath) + javaMainArgs.add(1, runnerType as String) } @@ -101,7 +143,7 @@ class JavaProcessRunner { } void consomeOutAndWait() { - process.consumeProcessOutput(System.out,System.err) + process.consumeProcessOutput(System.out, System.err) exitCode = process.waitFor() } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/LogExitTimeHook.groovy b/src/net/sf/jremoterun/utilities/nonjdk/LogExitTimeHook.groovy index 124ccf72..cf6613cc 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/LogExitTimeHook.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/LogExitTimeHook.groovy @@ -12,6 +12,7 @@ public class LogExitTimeHook implements Runnable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); private static volatile boolean added = false; + public static volatile boolean systemExitCalled = false; public static void addShutDownHook() { if (added) { @@ -25,8 +26,9 @@ public class LogExitTimeHook implements Runnable { @Override public void run() { - log.info(new Date().toString()); + systemExitCalled = true System.out.println("exit " + new Date()); + log.info(new Date().toString()); } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/MainMethodRunner.groovy b/src/net/sf/jremoterun/utilities/nonjdk/MainMethodRunner.groovy index 62cfe5ae..e8edc63e 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/MainMethodRunner.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/MainMethodRunner.groovy @@ -13,7 +13,8 @@ class MainMethodRunner { static void run(ClRef cnr, List args) { Class cll = cnr.loadClass(JrrClassUtils.currentClassLoader) - JrrClassUtils.runMainMethod(cll, args.toArray(new String[0])) + String[] args2 = args.toArray(new String[0]) + JrrClassUtils.runMainMethod(cll, args2) } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/NetworkCheck.groovy b/src/net/sf/jremoterun/utilities/nonjdk/NetworkCheck.groovy index e9242522..640a3155 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/NetworkCheck.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/NetworkCheck.groovy @@ -16,42 +16,49 @@ import groovy.transform.CompileStatic; @CompileStatic -class NetworkCheck extends TestCase{ +class NetworkCheck extends TestCase { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static int timeoutInMs = 101_000; + + Document dumpConetent(URL url){ + String text1 = url.text + log.info "text for ${url} = ${text1}" + try { + return Jsoup.parse(text1) + } catch (Exception e) { + throw new Exception("failed parse ${text1}", e) + } + } - - void testCheckGithub(){ + void testCheckGithub() { URL url = new URL("https://github.com/") -// String text = url.text -// assert text.contains("GitHub, Inc.") - Document parse = Jsoup.parse(url, 10_1000) + Document parse = dumpConetent(url); +// Document parse = Jsoup.parse(url, timeoutInMs) Elements els = parse.select("h3") - - assert els.first()!=null + assert els.first() != null } - void testCheckMaven(){ + void testCheckMaven() { MavenId sample = new MavenId("log4j:log4j:1.2.17"); MavenCommonUtils mavenCommonUtils = new MavenCommonUtils() - String suffix = mavenCommonUtils.buildMavenPath(sample).replace('.jar','.pom') + String suffix = mavenCommonUtils.buildMavenPath(sample).replace('.jar', '.pom') URL url = new URL(mavenCommonUtils.mavenDefaultSettings.mavenServer + '/' + suffix); String text = url.text; assert text.contains("log4j") } - void testCheckMavenDownload(){ + void testCheckMavenDownload() { IvyDepResolver2.setDepResolver() MavenId sample = new MavenId("log4j:log4j:1.2.17"); MavenDependenciesResolver dependenciesResolver = MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver - assert dependenciesResolver!=null - dependenciesResolver.resolveAndDownloadDeepDependencies(sample,false,false); + assert dependenciesResolver != null + dependenciesResolver.resolveAndDownloadDeepDependencies(sample, false, false); } - - void testCheckAll(){ + void testCheckAll() { testCheckGithub() testCheckMaven() testCheckMavenDownload() diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ProxyAuth.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ProxyAuth.groovy index dfd61f51..8b611d8d 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/ProxyAuth.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/ProxyAuth.groovy @@ -5,6 +5,7 @@ import groovy.transform.CompileStatic; import java.net.Authenticator; import java.net.PasswordAuthentication; +// see : org.apache.ivy.util.url.IvyAuthenticator @CompileStatic public class ProxyAuth extends Authenticator { private PasswordAuthentication auth; diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ProxySetter.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ProxySetter.groovy index e0c26cc0..94c235f3 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/ProxySetter.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/ProxySetter.groovy @@ -2,6 +2,7 @@ package net.sf.jremoterun.utilities.nonjdk import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.net.ProxyTrackerI import java.util.logging.Logger @@ -22,6 +23,7 @@ class ProxySetter extends ProxySelector { public static String proxyPassword = 'proxyPassword' public static String proxySet = 'proxySet' public static List prefix = ['http', 'https', 'ftp',] + public ProxyTrackerI proxyTracker Set noProxyConcreatHosts = new HashSet<>() Set noProxyPatternHosts = new HashSet<>() @@ -79,6 +81,9 @@ class ProxySetter extends ProxySelector { } } log.info "connecting to ${uri} ${useProxy}" + if(proxyTracker!=null) { + proxyTracker.accessRequested(uri, useProxy) + } if(useProxy){ return defaultProxy } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/SimpleUncaughtExceptionHandler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/SimpleUncaughtExceptionHandler.groovy index fa01fd80..ed9458f1 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/SimpleUncaughtExceptionHandler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/SimpleUncaughtExceptionHandler.groovy @@ -1,21 +1,22 @@ package net.sf.jremoterun.utilities.nonjdk -import groovy.transform.CompileStatic; +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils; import net.sf.jremoterun.utilities.JrrUtilities; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import java.lang.Thread.UncaughtExceptionHandler; +import java.lang.Thread.UncaughtExceptionHandler +import java.util.logging.Logger; @CompileStatic public class SimpleUncaughtExceptionHandler implements UncaughtExceptionHandler { - private static final Logger log = LogManager.getLogger(); + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static volatile boolean inited = false; public void uncaughtException(final Thread t, final Throwable e) { - log.info(t, e); + log.severe(t, e); JrrUtilities.showException("thread " + t.getId() + " " + t.getName(), e); } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/VersionComparator.groovy b/src/net/sf/jremoterun/utilities/nonjdk/VersionComparator.groovy new file mode 100644 index 00000000..ba609232 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/VersionComparator.groovy @@ -0,0 +1,122 @@ +package net.sf.jremoterun.utilities.nonjdk + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.junit.Test + +import java.util.logging.Logger; + +@CompileStatic +class VersionComparator implements Comparator { + + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static Map DEFAULT_SPECIAL_MEANINGS_default; + + public Map DEFAULT_SPECIAL_MEANINGS = [:]; + List badWords = [] + + static { + DEFAULT_SPECIAL_MEANINGS_default = new HashMap(); + DEFAULT_SPECIAL_MEANINGS_default.put("dev", new Integer(-1)); + DEFAULT_SPECIAL_MEANINGS_default.put("rc", new Integer(1)); + DEFAULT_SPECIAL_MEANINGS_default.put("final", new Integer(2)); + } + + VersionComparator() { + DEFAULT_SPECIAL_MEANINGS.putAll(DEFAULT_SPECIAL_MEANINGS_default) + } + + @Test + void test1(){ + assert compare('1.2.1','1.3.1') < 0 + assert compare('1.2.1','1.31.1') < 0 + assert compare('1.21.1','1.3.1') > 0 + assert compare('1.21','1.3.1') > 0 + assert compare('1.2','1.31.1') < 0 + assert compare('1.2','1.2') ==0 + assert compare('1.2dev','1.31.1') < 0 + + } + +/** + * + * return 1 if versionSaved > versionCandidate + */ + @Override + int compare(String versionSaved, String versionCandidate) { + versionSaved = versionSaved.toLowerCase() + versionCandidate = versionCandidate.toLowerCase() + + boolean savedHasNonStableVersion = badWords.find { + versionSaved.contains(it) + } != null + boolean candidateHasNonStableVersion = badWords.find { + versionCandidate.contains(it) + } != null + if (savedHasNonStableVersion && !candidateHasNonStableVersion) { + return 1 + } + if (!savedHasNonStableVersion && candidateHasNonStableVersion) { +// log.info "vs = ${versionCandidate} ${versionSaved}" + return -1 + } + int res = isOverrideMavenId(versionSaved, versionCandidate) + return res + } + + + int isOverrideMavenId(String rev1, String rev2) { + + rev1 = rev1.replaceAll('([a-zA-Z])(\\d)', '$1.$2'); + rev1 = rev1.replaceAll('(\\d)([a-zA-Z])', '$1.$2'); + rev2 = rev2.replaceAll('([a-zA-Z])(\\d)', '$1.$2'); + rev2 = rev2.replaceAll('(\\d)([a-zA-Z])', '$1.$2'); + + String[] parts1 = rev1.split('[\\._\\-\\+]'); + String[] parts2 = rev2.split('[\\._\\-\\+]'); + + int i = 0; + for (; i < parts1.length && i < parts2.length; i++) { + if (parts1[i].equals(parts2[i])) { + continue; + } + boolean is1Number = isNumber(parts1[i]); + boolean is2Number = isNumber(parts2[i]); + if (is1Number && !is2Number) { + return 1; + } + if (is2Number && !is1Number) { + return -1; + } + if (is1Number && is2Number) { + return Long.valueOf(parts1[i]).compareTo(Long.valueOf(parts2[i])); + } + // both are strings, we compare them taking into account special meaning + Integer sm1 = (Integer) DEFAULT_SPECIAL_MEANINGS.get(parts1[i].toLowerCase(Locale.US)); + Integer sm2 = (Integer) DEFAULT_SPECIAL_MEANINGS.get(parts2[i].toLowerCase(Locale.US)); + if (sm1 != null) { + sm2 = sm2 == null ? new Integer(0) : sm2; + return sm1.compareTo(sm2); + } + if (sm2 != null) { + return new Integer(0).compareTo(sm2); + } + return parts1[i].compareTo(parts2[i]); + } + if (i < parts1.length) { + return isNumber(parts1[i]) ? 1 : -1; + } + if (i < parts2.length) { + return isNumber(parts2[i]) ? -1 : 1; + } + return 0; + } + + boolean isNumber(String str) { + return str.matches('\\d+'); + + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/antutils/JrrAntUtils.groovy b/src/net/sf/jremoterun/utilities/nonjdk/antutils/JrrAntUtils.groovy index d4d18ba6..c79cb2fd 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/antutils/JrrAntUtils.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/antutils/JrrAntUtils.groovy @@ -7,7 +7,7 @@ import java.util.logging.Logger class JrrAntUtils { - private static final Logger log = Logger.getLogger(JrrAntUtils.name); + private static final Logger log = Logger.getLogger(JrrAntUtils.getName()); public static AntBuilder ant = new AntBuilder() diff --git a/src/net/sf/jremoterun/utilities/nonjdk/antutils/JrrAntUtils2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/antutils/JrrAntUtils2.groovy new file mode 100644 index 00000000..0707eed7 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/antutils/JrrAntUtils2.groovy @@ -0,0 +1,53 @@ +package net.sf.jremoterun.utilities.nonjdk.antutils + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.UrlCLassLoaderUtils +import org.apache.tools.ant.taskdefs.Zip +import org.apache.tools.ant.types.ZipFileSet + +import java.util.logging.Logger + + +@CompileStatic +class JrrAntUtils2 { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + static Zip createZipTask() { + AntBuilder antBuilder = new AntBuilder() + Zip zip = new Zip() + zip.setProject(antBuilder.getAntProject()) + return zip; + } + + static List addClassesToZip(Class... clazz) { + List res = [] + for (Class cl : clazz) { + addClassToZip(cl); + } + return res + } + + static String convertClassName(Class clazz) { + return clazz.name.replace('.', '/') + '*' + } + + static String convertPackageName(Class clazz) { + return clazz.getPackage().getName().replace('.', '/') + '/**/*' + } + + + static ZipFileSet addClassToZip(Class clazz) { + ZipFileSet zipFileSet = new ZipFileSet() + zipFileSet.setDir UrlCLassLoaderUtils.getClassLocation(clazz) + zipFileSet.setIncludes convertClassName(clazz) + return zipFileSet + } + + +} + + + diff --git a/src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElement.groovy b/src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElement.groovy new file mode 100644 index 00000000..a9ae368b --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElement.groovy @@ -0,0 +1,21 @@ +package net.sf.jremoterun.utilities.nonjdk.antutils + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +interface ZipElement { + + public static String includesAll = "**/*"; + + String name(); + + File getBaseDir(); + + String getIncludes() + + String getExcludes() + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElement2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElement2.groovy new file mode 100644 index 00000000..71cf21d3 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElement2.groovy @@ -0,0 +1,20 @@ +package net.sf.jremoterun.utilities.nonjdk.antutils + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.ToFileRef2 + +@CompileStatic +interface ZipElement2 { + + public static String includesAll = "**/*"; + + String name(); + + ToFileRef2 getBaseDir(); + + String getIncludes() + + String getExcludes() + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElements.groovy b/src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElements.groovy new file mode 100644 index 00000000..bd6d94eb --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/antutils/ZipElements.groovy @@ -0,0 +1,97 @@ +package net.sf.jremoterun.utilities.nonjdk.antutils + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import org.apache.tools.ant.taskdefs.Zip +import org.apache.tools.ant.types.ZipFileSet + +import java.util.logging.Logger + +@CompileStatic +class ZipElements { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static Zip.Duplicate createDuplicateFailed() { + Zip.Duplicate duplicate = new Zip.Duplicate() + duplicate.setValue('fail') + return duplicate + } + + static Zip.WhenEmpty createEmptyFailed() { + Zip.WhenEmpty emptyFailed = new Zip.WhenEmpty() + emptyFailed.setValue('fail') + return emptyFailed + } + + static Zip createArchive(File destFile, List els) { + assert destFile.parentFile.exists() + Zip zip = JrrAntUtils2.createZipTask() + els.collect { + try { + createZipFileSet(it) + }catch(Throwable e){ + log.info "failed handle ${it} : ${e}" + throw e + } + }.each { zip.addZipfileset(it) } + zip.setDestFile(destFile) + zip.setUpdate(false) + zip.setDuplicate(createDuplicateFailed()) + zip.setWhenempty(createEmptyFailed()) + destFile.delete() + assert !destFile.exists() + return zip + } + + + static Zip createArchive2(File destFile, List els) { + assert destFile.parentFile.exists() + Zip zip = JrrAntUtils2.createZipTask() + els.collect { + try { + createZipFileSet(it) + }catch(Throwable e){ + log.info "failed handle ${it} : ${e}" + throw e + } + }.each { zip.addZipfileset(it) } + zip.setDestFile(destFile) + zip.setUpdate(false) + zip.setDuplicate(createDuplicateFailed()) + zip.setWhenempty(createEmptyFailed()) + destFile.delete() + assert !destFile.exists() + return zip + } + + static ZipFileSet createZipFileSet(ZipElement location) { + File baseDir1 = location.getBaseDir() + JrrUtilities.checkFileExist(baseDir1) + ZipFileSet zipFileSet = new ZipFileSet() + zipFileSet.setDir(baseDir1) + zipFileSet.setIncludes(location.getIncludes()) + String excludes = location.getExcludes() + if (excludes != null) { + zipFileSet.setExcludes(excludes) + } + zipFileSet.setPrefix(location.name()) + return zipFileSet + } + + + static ZipFileSet createZipFileSet(ZipElement2 location) { + File baseDir1 = location.getBaseDir().resolveToFile() + JrrUtilities.checkFileExist(baseDir1) + ZipFileSet zipFileSet = new ZipFileSet() + zipFileSet.setDir(baseDir1) + zipFileSet.setIncludes(location.getIncludes()) + String excludes = location.getExcludes() + if (excludes != null) { + zipFileSet.setExcludes(excludes) + } + zipFileSet.setPrefix(location.name()) + return zipFileSet + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/apprunner/ProgramInfo.java b/src/net/sf/jremoterun/utilities/nonjdk/apprunner/ProgramInfo.java index 527a777e..6471b23b 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/apprunner/ProgramInfo.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/apprunner/ProgramInfo.java @@ -25,4 +25,7 @@ public interface ProgramInfo { void runProcess(); + + boolean allowManyProcessesMatched(); + } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/apprunner/ProgramRunner.groovy b/src/net/sf/jremoterun/utilities/nonjdk/apprunner/ProgramRunner.groovy index b35a16d0..821edcf5 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/apprunner/ProgramRunner.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/apprunner/ProgramRunner.groovy @@ -2,6 +2,7 @@ package net.sf.jremoterun.utilities.nonjdk.apprunner import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.nonjdk.AppRunner import net.sf.jremoterun.utilities.nonjdk.WinProcessesFinder import org.jvnet.winp.WinProcess @@ -14,7 +15,7 @@ class ProgramRunner { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - public void f1(ProgramInfo programInfo) { + public void startProcessIfNeeded(ProgramInfo programInfo) { if (checkProcessRunning(programInfo)) { log.info "program running : ${programInfo.name()}" } else { @@ -33,14 +34,28 @@ class ProgramRunner { } } - boolean checkProcessRunning(ProgramInfo contains) { - List listOfProcesses = WinProcessesFinder.findAllProcesses() - List processes = listOfProcesses.findAll { contains.matches(it.commandLine) } - if (processes.size() > 1) { - throw new Exception("too many processes for ${contains} ${processes.size()} ${processes.collect { it.commandLine }})}") + boolean checkProcessRunning(ProgramInfo programInfo) { + try { + List listOfProcesses = WinProcessesFinder.findAllProcesses() + List processes = listOfProcesses.findAll { programInfo.matches(it.commandLine) } +// processes.findAll{it.pare} + if (programInfo.allowManyProcessesMatched() && processes.size() > 1) { + return true; + } + if (processes.size() > 1) { + List procInfo2 =processes.collect { "${it.getPid()} ${it.getCommandLine()}".toString() } + log.info "too many processes for ${programInfo} ${processes.size()} ${procInfo2}" + throw new Exception("too many processes for ${programInfo} ${processes.size()} ${procInfo2}") + } + return processes.size() == 1 + }catch(Throwable e){ + onException(programInfo, e) } - return processes.size() == 1 } + void onException(ProgramInfo programInfo,Throwable e){ + JrrUtilities.showException("Failed check ${programInfo}", e); + } + } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/apprunner/RunProgramOnStart2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/apprunner/RunProgramOnStart2.groovy index f5c26297..f483bbc7 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/apprunner/RunProgramOnStart2.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/apprunner/RunProgramOnStart2.groovy @@ -1,11 +1,11 @@ package net.sf.jremoterun.utilities.nonjdk.apprunner -import groovy.transform.CompileStatic; -import net.sf.jremoterun.JrrUtils; +import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.MBeanFromJavaBean; -import net.sf.jremoterun.utilities.nonjdk.AppRunner; +import net.sf.jremoterun.utilities.nonjdk.AppRunner import net.sf.jremoterun.utilities.nonjdk.InitGeneral +import net.sf.jremoterun.utilities.nonjdk.nativeprocess.NativeProcessResult import net.sf.jremoterun.utilities.nonjdk.timer.AdjustPeriodTimer import net.sf.jremoterun.utilities.nonjdk.timer.TimerStyle @@ -18,57 +18,70 @@ abstract class RunProgramOnStart2 { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - public static int jmxPort = 7652; + AdjustPeriodTimer adjustPeriodTimer + + ProgramRunner programRunner = new ProgramRunner(); + + public static volatile long logProcessRunningInSec = 3600*6; + /** + * delay in ms + */ + int runProcessedOnStartDelay = 60_000 void runProgramsFromTimer() { log.info("start checking from timer"); ProgramRunner programRunner = new ProgramRunner(); for (ProgramInfo homeProgram : getMonitoredProcesses()) { - programRunner.f1(homeProgram); + programRunner.startProcessIfNeeded(homeProgram); } log.info("finish check from timer"); } + /** + * @param period in milli seconds + * @throws Exception + */ void runProgramOnStart3(long period) throws Exception { runProgramOnStart() -// Scheduler.scheduleOnceInAnyThread(10,TimeUnit.MINUTES,{ - AdjustPeriodTimer adjustPeriodTimer = new AdjustPeriodTimer(period, TimerStyle.Consecutive, { + adjustPeriodTimer = new AdjustPeriodTimer(period, TimerStyle.Consecutive, { runProgramsFromTimer(); }) adjustPeriodTimer.start2() -// }); MBeanFromJavaBean.registerMBean(adjustPeriodTimer, new ObjectName("jrrutils:timer=apprunner")) -// JrrTimerTask2 jrrTimerTask2 =new JrrTimerTask2(); -// jrrTimerTask2. - - } - void runProgramOnStart() throws Exception { - JrrUtils.creatJMXConnectorAndRMIRegistry(null,jmxPort,null,null); InitGeneral.init1(); AppRunner appRunner = new AppRunner() { @Override - public void runProcesses() { - ProgramRunner programRunner = new ProgramRunner(); - for (ProgramInfo homeProgram : getMonitoredProcesses()) { - if (programRunner.checkProcessRunning(homeProgram)) { - log.info("program running : " + homeProgram); - } else { - homeProgram.runProcess(); - } - + void runProcesses() { + for (ProgramInfo programInfo : getMonitoredProcesses()) { + checkProgramOnStart(programInfo) } } }; appRunner.taskGroupName = "Run process on start"; - appRunner.sleepTime = 150_000; + appRunner.sleepTime = runProcessedOnStartDelay; appRunner.askToRunNewThread(); } + void checkProgramOnStart(ProgramInfo programInfo) { + if (programRunner.checkProcessRunning(programInfo)) { + log.info("program running : " + programInfo); + } else { + programInfo.runProcess(); + } + + } + + static Thread defaultProcessRunnerInNewThread(ProgramInfo programInfo, File genericLogDir, int rotationDepth) { + return new RunProgramOnStart3(programInfo,genericLogDir,rotationDepth).defaultProcessRunnerInNewThread() + } + + + abstract List getMonitoredProcesses(); } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/apprunner/RunProgramOnStart3.groovy b/src/net/sf/jremoterun/utilities/nonjdk/apprunner/RunProgramOnStart3.groovy new file mode 100644 index 00000000..c74bd0dc --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/apprunner/RunProgramOnStart3.groovy @@ -0,0 +1,64 @@ +package net.sf.jremoterun.utilities.nonjdk.apprunner + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.MBeanFromJavaBean +import net.sf.jremoterun.utilities.nonjdk.AppRunner +import net.sf.jremoterun.utilities.nonjdk.InitGeneral +import net.sf.jremoterun.utilities.nonjdk.nativeprocess.NativeProcessResult +import net.sf.jremoterun.utilities.nonjdk.timer.AdjustPeriodTimer +import net.sf.jremoterun.utilities.nonjdk.timer.TimerStyle + +import javax.management.ObjectName +import java.util.logging.Logger + +@CompileStatic +class RunProgramOnStart3 { + + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public ProgramInfo programInfo; + public File genericLogDir; + public int rotationDepth; + public NativeProcessResult processResult; + public Thread thread + public List env = NativeProcessResult.defaultEnv; + + RunProgramOnStart3(ProgramInfo programInfo, File genericLogDir, int rotationDepth) { + this.programInfo = programInfo + this.genericLogDir = genericLogDir + this.rotationDepth = rotationDepth + } + + void defaultProcessRunnerInNewThread() { + Runnable r = { + defaultProcessRunner() + } + thread = new Thread(r, "Jrr app runner for ${programInfo}") + thread.start() + thread.join(1000) + } + + void defaultProcessRunner() { + log.info("running " + programInfo); + File child = genericLogDir.child(programInfo.name()) + child.mkdir() + assert child.exists() + File outFile = child.child('out.txt') + //NativeProcessResult.runNativeProcessAndWait(programInfo.getRunFile().absolutePath, programInfo.getRunFile().getParentFile()) + runProcessImpl() + //processResult.timeoutInSec = logProcessRunningInSec; + processResult.addWriteOutToFile(outFile,rotationDepth) + processResult.waitAsyncM() + //GeneralUtils.runNativeProcessRedirectOutputToFile(programInfo.getRunFile().absolutePath, programInfo.getRunFile().getParentFile(), false, outFile, rotationDepth); + log.info("started : " + programInfo); + } + + void runProcessImpl(){ + Process process = programInfo.getRunFile().getAbsolutePath().execute(env, programInfo.getRunFile().getParentFile()); + processResult = new NativeProcessResult(process) + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/awtdebug/EventQueueDebug.groovy b/src/net/sf/jremoterun/utilities/nonjdk/awtdebug/EventQueueDebug.groovy index 41e89a66..880f77ae 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/awtdebug/EventQueueDebug.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/awtdebug/EventQueueDebug.groovy @@ -65,7 +65,7 @@ class EventQueueDebug extends EventQueue { } else { String className = data.getClass().getName() switch (className) { - case { className.startsWith(sun.awt.windows.WInputMethod.getName()) }: + case { className.startsWith(winWInputMethodClass.getClassName()) }: InputMethodAdapter imppl2 = (InputMethodAdapter) inputMethod.get(data) Component component3 = (Component) inputMethod2.get(imppl2) break @@ -87,6 +87,11 @@ class EventQueueDebug extends EventQueue { } + + + ClRef winWInputMethodClass = new ClRef('sun.awt.windows.WInputMethod') + ClRef winWComponentPeerClass = new ClRef('sun.awt.windows.WComponentPeer') + void printEventInfoImpl(AWTEvent theEvent) { String eventClassName = theEvent.getClass().getName() if (theEvent instanceof java.awt.event.KeyEvent) { @@ -120,10 +125,10 @@ class EventQueueDebug extends EventQueue { case { className.startsWith(sun.awt.GlobalCursorManager.getName()) }: globalCursorManager.newEvent(); break; - case { className.startsWith(sun.awt.windows.WComponentPeer.getName()) }: + case { className.startsWith(winWComponentPeerClass.getClassName()) }: WComponentPeer.newEvent(); break; - case { className.startsWith(sun.awt.windows.WInputMethod.getName()) }: + case { className.startsWith(winWInputMethodClass.getClassName()) }: InputMethodAdapter imppl2 = (InputMethodAdapter) inputMethod.get(data) Component component3 = (Component) inputMethod2.get(imppl2) if (component3 == null) { diff --git a/src/net/sf/jremoterun/utilities/nonjdk/cacheddata/CachedData.groovy b/src/net/sf/jremoterun/utilities/nonjdk/cacheddata/CachedData.groovy new file mode 100644 index 00000000..99531fcc --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/cacheddata/CachedData.groovy @@ -0,0 +1,24 @@ +package net.sf.jremoterun.utilities.nonjdk.cacheddata + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.commons.codec.binary.Base64 + +import java.security.MessageDigest; +import java.util.logging.Logger; + +@CompileStatic +class CachedData { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public static MessageDigest messageDigest = MessageDigest.getInstance('SHA-256'); + + + static String getDigest(String query) { + byte[] digest = messageDigest.digest(query.getBytes()) + return new String(Base64.encodeBase64(digest)).replace('/', '-').replace('/', '-') + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/AddDirectoryWithFiles.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/AddDirectoryWithFiles.groovy new file mode 100644 index 00000000..c71c5c09 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/AddDirectoryWithFiles.groovy @@ -0,0 +1,53 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon +import net.sf.jremoterun.utilities.classpath.ClassPathCalculatorWithAdder +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.AddToAdderSelf; + +import java.util.logging.Logger; + +@CompileStatic +class AddDirectoryWithFiles implements AddToAdderSelf { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public File baseDir; + public List excludeFiles = []; + + public ClassPathCalculatorWithAdder classPathCalculatorWithAdder = new ClassPathCalculatorWithAdder() { + @Override + protected void addElement2(Object obj) { + boolean needAdd = false + if (obj instanceof File) { + File file = (File) obj; + needAdd = needAcceptFile(file) + } else { + needAdd = true + } + if (needAdd) { + super.addElement2(obj) + } + } + } + + boolean needAcceptFile(File file) { + if (excludeFiles.contains(file.getName())) { + return false + } + return true; + + } + + AddDirectoryWithFiles(File baseDir, List excludeFiles) { + this.baseDir = baseDir + this.excludeFiles = excludeFiles + } + + @Override + void addToAdder(AddFilesToClassLoaderCommon adder) { + classPathCalculatorWithAdder.addFilesToClassLoaderGroovySave.addAllJarsInDirAndSubdirsDeep(baseDir) + adder.addAll(classPathCalculatorWithAdder.filesAndMavenIds) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerImpl.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerImpl.groovy index c3b4f5ab..a8b8e3d8 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerImpl.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerImpl.groovy @@ -3,29 +3,51 @@ package net.sf.jremoterun.utilities.nonjdk.classpath import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon +import net.sf.jremoterun.utilities.classpath.AddFilesWithSourcesI import net.sf.jremoterun.utilities.classpath.BinaryWithSource import net.sf.jremoterun.utilities.classpath.CustomObjectHandler import net.sf.jremoterun.utilities.classpath.MavenCommonUtils +import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.classpath.MavenDependenciesResolver +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepo +import net.sf.jremoterun.utilities.classpath.MavenIdAndRepoContains +import net.sf.jremoterun.utilities.classpath.MavenIdContains import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkResourceDirs +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs +import net.sf.jremoterun.utilities.nonjdk.InfocationFrameworkStructure +import net.sf.jremoterun.utilities.nonjdk.JavaVersionChecker +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.AddToAdderSelf +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileToFileRef import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.RefLink +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.UnzipRef +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.ZeroOverheadFileRef import net.sf.jremoterun.utilities.nonjdk.downloadutils.UrlDownloadUtils3 -import net.sf.jremoterun.utilities.nonjdk.git.CloneGitRepo2 + import net.sf.jremoterun.utilities.nonjdk.git.CloneGitRepo4 import net.sf.jremoterun.utilities.nonjdk.git.GitBinaryAndSourceRef import net.sf.jremoterun.utilities.nonjdk.git.GitBinaryAndSourceRefRef import net.sf.jremoterun.utilities.nonjdk.git.GitRef import net.sf.jremoterun.utilities.nonjdk.git.GitRefRef +import net.sf.jremoterun.utilities.nonjdk.git.GitRepoUtils import net.sf.jremoterun.utilities.nonjdk.git.GitSpec -import net.sf.jremoterun.utilities.nonjdk.git.SvnRef +import net.sf.jremoterun.utilities.nonjdk.git.GitSpecRef import net.sf.jremoterun.utilities.nonjdk.git.SvnSpec +import net.sf.jremoterun.utilities.nonjdk.git.SvnSpecRef import net.sf.jremoterun.utilities.nonjdk.git.ToFileRefRedirect +import net.sf.jremoterun.utilities.nonjdk.git.UrlSymbolsReplacer import net.sf.jremoterun.utilities.nonjdk.sfdownloader.SfLink import net.sf.jremoterun.utilities.nonjdk.sfdownloader.SourceForgeDownloader import net.sf.jremoterun.utilities.nonjdk.sfdownloader.UrlProvided import net.sf.jremoterun.utilities.nonjdk.svn.SvnUtils import org.apache.commons.io.FileUtils +import org.zeroturnaround.zip.ZipUtil import java.util.logging.Logger +import java.util.zip.ZipFile @CompileStatic class CustomObjectHandlerImpl implements CustomObjectHandler { @@ -42,12 +64,17 @@ class CustomObjectHandlerImpl implements CustomObjectHandler { UrlDownloadUtils3 urlDownloadUtils = new UrlDownloadUtils3() - File gitTmpDir + File gitTmpDir; + File androidUnArchive; - SvnUtils svnUtils + SvnUtils svnUtils; + static CustomObjectHandlerImpl getSelfRef(){ + MavenDefaultSettings.mavenDefaultSettings.customObjectHandler as CustomObjectHandlerImpl; + } CustomObjectHandlerImpl(File gitRepo) { + JavaVersionChecker.checkJavaVersion(); cloneGitRepo3 = new CloneGitRepo4(gitRepo); replicaDir = new File(gitRepo, 'replica') replicaDir.mkdir() @@ -57,46 +84,251 @@ class CustomObjectHandlerImpl implements CustomObjectHandler { assert sfDir.exists() sfDownloader = new SourceForgeDownloader(sfDir) this.gitTmpDir = new File(gitRepo, "tmp") + this.androidUnArchive = new File(gitRepo, "android") gitTmpDir.mkdir() svnUtils = new SvnUtils(gitRepo, gitTmpDir) } + @Override + File resolveToFileIfDownloaded(Object object) { + switch (object) { +// case { object instanceof RefLink }: +// RefLink refLink = (RefLink) object +// return resolveToFile(refLink.enumm) +// case { object instanceof ToFileRefRedirect }: +// ToFileRefRedirect toFileRefRedirect = (ToFileRefRedirect) object +// ToFileRef2 redirect = toFileRefRedirect.getRedirect() +// assert redirect != null +// return resolveToFile(redirect) + case { object instanceof ZeroOverheadFileRef }: + ZeroOverheadFileRef fileToFileRef = object as ZeroOverheadFileRef; + return fileToFileRef.resolveToFile(); + case { object instanceof UnzipRef }: + return resolveUnzipIfDownloaded(object as UnzipRef) + case { object instanceof FileChildLazyRef }: + FileChildLazyRef refLink2 = (FileChildLazyRef) object + return resolveLazyChildOfDownloaded(refLink2) + case { object instanceof SfLink }: + SfLink sfLink = object as SfLink + return sfDownloader.resolveIfDownloaded(sfLink) + case { object instanceof GitRefRef }: + GitRefRef gitRef = (GitRefRef) object; + return resolveRefIfDownloaded(gitRef.ref) + case { object instanceof GitSpecRef }: + GitSpecRef gitSpec = (GitSpecRef) object; + return cloneGitRepo3.getFileIfDownloaded(gitSpec.getGitSpec()) + case { object instanceof UrlProvided }: + return resolveToFileIfDownloaded(((UrlProvided) object).convertToUrl()) + case { object instanceof IfFrameworkResourceDirs }: + IfFrameworkResourceDirs resourceDirs = object as IfFrameworkResourceDirs + if(InfocationFrameworkStructure.ifDir!=null){ + return resourceDirs.resolveToFile() + } + log.info("need define InfocationFrameworkStructure.ifDir to resolve : ${object}") + return null; + case { object instanceof IfFrameworkSrcDirs }: + IfFrameworkSrcDirs resourceDirs = object as IfFrameworkSrcDirs + if(InfocationFrameworkStructure.ifDir!=null){ + return resourceDirs.resolveToFile() + } + log.info("need define InfocationFrameworkStructure.ifDir to resolve : ${object}") + return null; + case { object instanceof SvnSpecRef }: + SvnSpecRef svnRef = object as SvnSpecRef + return getSvnRefIfDownloaded(svnRef.getSvnSpec()) +// case { object instanceof AndroidArchive }: +// AndroidArchive aar = (AndroidArchive) object; +// return downloadAndroid(aar); +// case { object instanceof UrlProvided }: +// UrlProvided u = object as UrlProvided +// URL url = u.convertToUrl() +// return urlDownloadUtils.downloadUrl(url) +// case { object instanceof MavenIdContains }: +// MavenIdContains u = object as MavenIdContains +// MavenId mavenId = u.getM() +// return mavenId.resolveToFile() +// case { object instanceof ToFileRef2 }: +// ToFileRef2 u = object as ToFileRef2 +// return u.resolveToFile() + default: + log.info("not supported : ${object.class.name} ${object}") + return null + } + } + @Override File resolveToFile(Object object) { switch (object) { + case { object instanceof FileChildLazyRef }: + FileChildLazyRef refLink2 = (FileChildLazyRef) object + return resolveLazyChild(refLink2) case { object instanceof RefLink }: RefLink refLink = (RefLink) object return resolveToFile(refLink.enumm) case { object instanceof ToFileRefRedirect }: ToFileRefRedirect toFileRefRedirect = (ToFileRefRedirect) object ToFileRef2 redirect = toFileRefRedirect.getRedirect() - assert redirect!=null + assert redirect != null return resolveToFile(redirect) + case { object instanceof UnzipRef }: + return downloadAndResolveUnzip(object as UnzipRef) case { object instanceof SfLink }: SfLink sfLink = object as SfLink return sfDownloader.download(sfLink) case { object instanceof GitRefRef }: GitRefRef gitRef = (GitRefRef) object; return resolveRef(gitRef.ref) - case { object instanceof GitSpec }: - GitSpec gitSpec = (GitSpec) object; - return cloneGitRepo3.cloneGitRepo3(gitSpec) + case { object instanceof GitSpecRef }: + GitSpecRef gitSpec = (GitSpecRef) object; + return cloneGitRepo3.cloneGitRepo3(gitSpec.getGitSpec()) case { object instanceof SvnSpec }: SvnSpec svnRef = object as SvnSpec return resolveSvnRef(svnRef) + case { object instanceof AndroidArchive }: + AndroidArchive aar = (AndroidArchive) object; + return downloadAndroid(aar); case { object instanceof UrlProvided }: UrlProvided u = object as UrlProvided URL url = u.convertToUrl() return urlDownloadUtils.downloadUrl(url) + case { object instanceof MavenIdAndRepoContains }: + MavenIdAndRepoContains u2 = object as MavenIdAndRepoContains + MavenIdAndRepo mavenId2 = u2.getMavenIdAndRepo() + return mavenId2.resolveToFile() + + case { object instanceof MavenIdContains }: + MavenIdContains u = object as MavenIdContains + MavenId mavenId = u.getM() + return mavenId.resolveToFile() + case { object instanceof ToFileRef2 }: + ToFileRef2 u = object as ToFileRef2 + return u.resolveToFile() default: throw new IllegalArgumentException("${object.class.name} ${object}") + + } + + } + + String resolvePathForRef(ToFileRef2 ref) { + if (ref == null) { + throw new NullPointerException('ref is null') + } + if (ref instanceof UrlProvided) { + return urlDownloadUtils.mcu.buildDownloadUrlSuffix(ref.convertToUrl()) + } + if (ref instanceof SvnSpec) { + return UrlSymbolsReplacer.replaceBadSymbols(ref.repo) + } + if (ref instanceof GitSpec) { + return CloneGitRepo4.createGitRepoSuffix(ref.repo); + } + if (ref instanceof FileChildLazyRef) { + String parent = resolvePathForRef(ref.parentRef) + return parent + '/' + ref.child; + } + if (ref instanceof MavenIdAndRepoContains) { + return resolvePathForRef(ref.getMavenIdAndRepo().m) + } + if (ref instanceof MavenIdContains) { + MavenId mavenId = ref.m + String childd = mavenId.toString() + childd = childd.replace(':', '/') + return "maven/${childd}" + } + throw new UnsupportedOperationException("${ref.getClass().getName()} ${ref}") + } + + File resolveUnzipIfDownloaded(UnzipRef ref) { + File zipFile = resolveToFileIfDownloaded(ref.refToZip) + if (zipFile == null) { + return null + } + String suffix = resolvePathForRef(ref.refToZip); + File f = urlDownloadUtils.unzipDir.child(suffix) + if (!f.exists()) { + log.info "file not exist : ${f}" + return null } + return f + } + File downloadAndResolveUnzip(UnzipRef ref) { + File zipFile = resolveToFile(ref.refToZip) + String suffix = resolvePathForRef(ref.refToZip); + return urlDownloadUtils.unzip(zipFile, suffix) + } + + File resolveLazyChild(FileChildLazyRef childLazyRef) { + File parentRefResolved = childLazyRef.parentRef.resolveToFile() + if (parentRefResolved == null) { + throw new IOException("Failed resolve : ${childLazyRef.parentRef}") + } + if (!parentRefResolved.exists()) { + throw new FileNotFoundException(parentRefResolved.getAbsolutePath()) + } + File childFile = parentRefResolved.child(childLazyRef.child) + if (!childFile.exists()) { + throw new FileNotFoundException(childFile.getAbsolutePath()) + } + return childFile + } + + + File resolveLazyChildOfDownloaded(FileChildLazyRef childLazyRef) { + File parentRefResolved = resolveToFileIfDownloaded(childLazyRef.parentRef); + if (parentRefResolved == null) { + return null + } + if (!parentRefResolved.exists()) { + return null + } + File childFile = parentRefResolved.child(childLazyRef.child) + if (!childFile.exists()) { + throw new FileNotFoundException(childFile.getAbsolutePath()) + } + return childFile + } + + File downloadAndroid(AndroidArchive androidArchive) { + File someDir = new File(mcu.mavenDefaultSettings.grapeLocalDir, "${androidArchive.m.groupId}/${androidArchive.m.artifactId}") + + File aarFile = new File(someDir, "aars/${androidArchive.m.artifactId}-${androidArchive.m.version}.aar") + if (!aarFile.exists()) { + + MavenDependenciesResolver ivyDepResolver2 = MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver + List dependencies = ivyDepResolver2.resolveAndDownloadDeepDependencies(androidArchive.m, false, false) + log.info "${dependencies}" + if (!aarFile.exists()) { + throw new FileNotFoundException("Failed resolve ${androidArchive} ${aarFile}") + } + } + File toFile = new File(androidUnArchive, "${androidArchive.m.groupId}/${androidArchive.m.artifactId}/${androidArchive.m.artifactId}-${androidArchive.m.version}.jar") + if (toFile.exists()) { + return toFile + } + File parentFile = toFile.getParentFile() + parentFile.mkdirs() + if (!parentFile.exists()) { + throw new IOException("Failed create : ${parentFile}") + } + boolean unpacked = ZipUtil.unpackEntry(new ZipFile(aarFile), "classes.jar", toFile) + if (!unpacked) { + throw new IOException("Failed find classes.jar in : ${aarFile}") + } + if (!toFile.exists()) { + throw new IOException("Failed extract classes.jar from : ${aarFile}") + } + return toFile } @Override void add(AddFilesToClassLoaderCommon adder, Object object) { switch (object) { + case { object instanceof AddToAdderSelf }: + AddToAdderSelf addToAdderSelf = object as AddToAdderSelf; + addToAdderSelf.addToAdder(adder) + break case { object instanceof RefLink }: RefLink refLink = (RefLink) object adder.addGenericEntery(refLink.enumm) @@ -105,13 +337,24 @@ class CustomObjectHandlerImpl implements CustomObjectHandler { case { object instanceof ToFileRefRedirect }: ToFileRefRedirect toFileRefRedirect = (ToFileRefRedirect) object ToFileRef2 redirect = toFileRefRedirect.getRedirect() - assert redirect!=null - add(adder,redirect) + assert redirect != null + add(adder, redirect) break case { object instanceof GitBinaryAndSourceRefRef }: GitBinaryAndSourceRefRef gitRef = (GitBinaryAndSourceRefRef) object; addGitRef(adder, gitRef.ref) break; + case { object instanceof AndroidArchive }: + AndroidArchive aar = (AndroidArchive) object; + File f = downloadAndroid(aar); + adder.add f + if (adder instanceof AddFilesWithSourcesI) { + File sourceFile = adder.addSourceMNoExceptionOnMissing aar.m; + if (sourceFile == null) { + log.info "not source for android artifact : ${aar.m}" + } + } + break default: File f = resolveToFile(object) adder.add f @@ -120,17 +363,32 @@ class CustomObjectHandlerImpl implements CustomObjectHandler { } + File getSvnRefIfDownloaded(SvnSpec svnRef) { + File checkout = svnUtils.getFileIfDownloaded(svnRef) +// if (!(svnRef instanceof SvnRef)) { + return checkout +// } +// if (checkout == null || !checkout.exists()) { +// return null +// } +// File fileInRepo = checkout.child(svnRef.pathInRepo) +// if (!fileInRepo.exists()) { +// throw new FileNotFoundException("failed find ${svnRef}") +// } +// return fileInRepo + } + File resolveSvnRef(SvnSpec svnRef) { File checkout = svnUtils.svnCheckout(svnRef) - if (!(svnRef instanceof SvnRef)) { +// if (!(svnRef instanceof SvnRef)) { return checkout - } - File fileInRepo = checkout.child(svnRef.pathInRepo) - if (!fileInRepo.exists()) { - throw new FileNotFoundException("failed find ${svnRef}") - } - fileInRepo = getRef23(fileInRepo) - return fileInRepo +// } +// File fileInRepo = checkout.child(svnRef.pathInRepo) +// if (!fileInRepo.exists()) { +// throw new FileNotFoundException("failed find ${svnRef}") +// } +// fileInRepo = getRef23(fileInRepo) +// return fileInRepo } public boolean updateRepoIfRefNotExists = true @@ -142,7 +400,7 @@ class CustomObjectHandlerImpl implements CustomObjectHandler { boolean allFound = bin.exists() && src.exists() if (!allFound && updateRepoIfRefNotExists) { log.info "updating repo : ${gitRef}" - CloneGitRepo2.updateGitRepo2(gitRef) + GitRepoUtils.updateGitRepo2(gitRef) } if (!bin.exists()) { throw new FileNotFoundException("bin not found : ${gitRef}") @@ -167,6 +425,21 @@ class CustomObjectHandlerImpl implements CustomObjectHandler { return fileInRepo } + File resolveRefIfDownloaded(GitRef gitRef) { + File gitRepo = cloneGitRepo3.getFileIfDownloaded(gitRef) + if (gitRepo == null || !gitRepo.exists()) { + return null; + } + + File fileInRepo = new File(gitRepo, gitRef.pathInRepo) + if (!fileInRepo.exists()) { + log.info "file not exist : ${fileInRepo} , ${gitRef}" + return fileInRepo + } + fileInRepo = getRef23(fileInRepo) + return fileInRepo + } + private File getRef23(File fileInRepo) { if (fileInRepo.isFile()) { String pathToParent = mcu.getPathToParent(cloneGitRepo3.gitBaseDir, fileInRepo) @@ -197,7 +470,7 @@ class CustomObjectHandlerImpl implements CustomObjectHandler { boolean needCopy = isCopyFileNeeded(src, dest) if (needCopy) { log.info("coping ${src} to ${dest}") - FileUtils.copyFile(src, dest) + FileUtilsJrr.copyFile(src, dest) dest.setLastModified(src.lastModified()) } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerSetter.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerSetter.groovy index 6b52984e..672991e4 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerSetter.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerSetter.groovy @@ -6,6 +6,7 @@ import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.groovystarter.runners.RunnableWithParamsFactory import net.sf.jremoterun.utilities.javassist.codeinjector.InjectedCode +import net.sf.jremoterun.utilities.nonjdk.JavaVersionChecker import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds import java.util.logging.Logger @@ -20,6 +21,7 @@ class CustomObjectHandlerSetter extends InjectedCode { @Override Object get(Object key) { + JavaVersionChecker.checkJavaVersion(); List list = key as List AddFilesToClassLoaderCommon adder = list[0] as AddFilesToClassLoaderCommon; assert adder!=null diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerSetter2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerSetter2.groovy index fc419d61..b8e6ef74 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerSetter2.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/CustomObjectHandlerSetter2.groovy @@ -6,6 +6,9 @@ import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.javassist.codeinjector.InjectedCode +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs +import net.sf.jremoterun.utilities.nonjdk.InfocationFrameworkStructure +import net.sf.jremoterun.utilities.nonjdk.JavaVersionChecker import java.util.logging.Logger @@ -24,9 +27,10 @@ class CustomObjectHandlerSetter2 extends InjectedCode { static void addSupport(File gitBase) { if (MavenDefaultSettings.mavenDefaultSettings.customObjectHandler == null) { - + JavaVersionChecker.checkJavaVersion(); CustomObjectHandlerImpl s = new CustomObjectHandlerImpl(gitBase) MavenDefaultSettings.mavenDefaultSettings.customObjectHandler = s + } else { log.info "customObjectHandler already set : ${MavenDefaultSettings.mavenDefaultSettings.customObjectHandler}" } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/MavenDepParser.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/MavenDepParser.groovy index 5896195c..78e61f0d 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/MavenDepParser.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/MavenDepParser.groovy @@ -1,6 +1,7 @@ package net.sf.jremoterun.utilities.nonjdk.classpath -import groovy.util.slurpersupport.GPathResult; +import groovy.util.slurpersupport.GPathResult +import groovy.util.slurpersupport.NodeChildren; import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenId; @@ -13,33 +14,75 @@ class MavenDepParser { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - static List findDepsFromPomXml(String text){ + List findDepsFromPomXml2(String text){ + GPathResult result = new XmlSlurper().parseText(text); + Collection deps2 =result.depthFirst().findAll {it.name() == 'dependency'} + if(deps2==null){ + throw new IllegalArgumentException("no dependencies element") + } + List mavenIds = deps2.collect {convertDepToMavenId(it)} + return mavenIds + + } + + + MavenId extractMavenId(String text){ + GPathResult xmlRes2 = new XmlSlurper().parseText(text); + Object xmlRes =xmlRes2 +// Object xmlRes =xmlRes2.result.depthFirst().findAll {it.name() == 'project'}[0] +// groovy.util.slurpersupport.Node xmlRes =xmlRes2.childNodes().next() + +// assert xmlRes!=null +// log.info "${xmlRes.getClass()}" + String group = xmlRes.groupId; +// log.info "group = ${group}" + String artifact = xmlRes.artifactId; + assert artifact!=null + assert artifact.length()>0 + assert group!=null + assert group.length()>0 + String version = xmlRes.version; + if(version==null || version.length()==0){ + //groovy.util.slurpersupport.NodeChildren + Object parent1 = xmlRes.parent + if(parent1==null){ + throw new Exception("Failed find version") + } + assert parent1!=null +// log.info "${parent1.getClass()}" + version= parent1.version + } + assert version!=null + assert version.length()>0 + + MavenId mavenId = new MavenId(group,artifact,version) + return mavenId + } + + List findDepsFromPomXml(String text){ GPathResult xmlRes = new XmlSlurper().parseText(text); Object deps2 = xmlRes.dependencies; if(deps2==null){ throw new IllegalArgumentException("no dependencies element") } List deps = deps2.dependency.list(); - List mavenIds = deps.collect { - String group = it.groupId; - String artifact = it.artifactId; - String version = it.version; - return new MavenId(group, artifact, version) - } + List mavenIds = deps.collect {convertDepToMavenId(it)} return mavenIds } - static List getDepsFromMavenDepSnippet(String text){ + MavenId convertDepToMavenId(Object obj){ + String group = obj.groupId; + String artifact = obj.artifactId; + String version = obj.version; + return new MavenId(group, artifact, version) + } + + List getDepsFromMavenDepSnippet(String text){ String s = " ${text} " GPathResult res = new XmlSlurper().parseText( s ); List deps = res.dependency.list(); - List mavenIds = deps.collect { - String group = it.groupId; - String artifact = it.artifactId; - String version = it.version; - return new MavenId(group, artifact, version) - } + List mavenIds = deps.collect {convertDepToMavenId(it)} return mavenIds } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/MavenDepParser2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/MavenDepParser2.groovy index de3ef79b..14d59416 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/MavenDepParser2.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/MavenDepParser2.groovy @@ -15,7 +15,7 @@ class MavenDepParser2 { static void findDep(File inFile,File outFile){ assert inFile.exists() - List deps = MavenDepParser.findDepsFromPomXml(inFile.text) + List deps = new MavenDepParser().findDepsFromPomXml(inFile.text) ClassPathCalculatorGitRefSup calculator = new ClassPathCalculatorGitRefSup() calculator.filesAndMavenIds.addAll deps outFile.text = calculator.saveClassPath9() diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/BintrayJarDownloader.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/BintrayJarDownloader.groovy new file mode 100644 index 00000000..5243a1fa --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/calchelpers/BintrayJarDownloader.groovy @@ -0,0 +1,66 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.TwoResult +import net.sf.jremoterun.utilities.nonjdk.classpath.search.BintraySearch +import net.sf.jremoterun.utilities.nonjdk.classpath.search.BintraySearchResult +import net.sf.jremoterun.utilities.nonjdk.ivy.ManyReposDownloaderImpl + +import java.util.logging.Logger; + +@CompileStatic +class BintrayJarDownloader { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public ManyReposDownloaderImpl mavenDownloader = new ManyReposDownloaderImpl(null); + + public BintraySearch bintraySearch = new BintraySearch() + public List files; + public List> exceptions = []; + public List resolved = []; + + void doStuff() { + readUnresolvedFiles() + List all1 = files.collect { bintraySearch.searchBySha1(it) }.collect { convert1(it) } + + + all1.each { + downloadResult(it) + resolved.add(it) + } + } + + void readUnresolvedFiles() { + Map filesMap = ClassPathCalculatorGroovyWithDownloadWise.readNoMavenIdsFile() + files = filesMap.keySet().toList() + files = files.findAll { needResolveFiles(it) } + } + + boolean needResolveFiles(File f) { + return f.exists(); + } + + + BintraySearchResult convert1(List list1) { + if (list1.size() == 1) { + return list1[0] + } + } + + + + void downloadResult(BintraySearchResult result) { + try { + mavenDownloader.resolveAndDownloadDeepDependencies(result.mavenId, true, false, result.bintrayRepo) + } catch (Exception e) { + onException(result, e) + } + } + + void onException(BintraySearchResult result, Throwable e) { + exceptions.add(new TwoResult(result, e)) + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/AddedLocationDetector.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/AddedLocationDetector.groovy new file mode 100644 index 00000000..11489d49 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/AddedLocationDetector.groovy @@ -0,0 +1,53 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.classloader + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.AddFileToClassloaderDummy +import net.sf.jremoterun.utilities.nonjdk.problemchecker.JustStackTrace +import org.zeroturnaround.zip.ZipEntryCallback +import org.zeroturnaround.zip.ZipUtil; + +import java.util.logging.Logger +import java.util.zip.ZipEntry; + +@CompileStatic +class AddedLocationDetector extends AddFilesToClassLoaderGroovy { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public Map> locationMap = [:] + + public List addedFiles3 = [] + + @Override + void addFile(File file) throws Exception { + file = file.getCanonicalFile().getAbsoluteFile(); + addedFiles3.add(file) + List locations = locationMap.get(file) + if (locations == null) { + locations = [] + locationMap.put(file, locations) + } + locations.add(new JustStackTrace()) + } + + List getAddedFiles4(){ + return addedFiles3.unique() + } + + @Override + void addFileImpl(File file) throws Exception { + throw new Exception('Should not be used') + } + + Map> findDuplicates() { + return locationMap.findAll { it.value.size() > 1 } + } + + void printDuplicates() { + Map> duplicates = findDuplicates() + } + + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/AllClasspathAnalysis.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/AllClasspathAnalysis.groovy new file mode 100644 index 00000000..982cb3aa --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/AllClasspathAnalysis.groovy @@ -0,0 +1,203 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.classloader + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon +import net.sf.jremoterun.utilities.classpath.ClassPathCalculatorAbstract +import net.sf.jremoterun.utilities.classpath.ClassPathCalculatorWithAdder +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.classpath.AddDirectoryWithFiles +import net.sf.jremoterun.utilities.nonjdk.classpath.CustomObjectHandlerImpl +import net.sf.jremoterun.utilities.nonjdk.problemchecker.JustStackTrace +import org.apache.commons.collections4.MapUtils + +import java.util.logging.Logger; + +@CompileStatic +class AllClasspathAnalysis { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public AddedLocationDetector adder = new AddedLocationDetector(); + public GetClassesFromLocation classesFromLocation; + public DuplicateClassesDetector duplicateClassesDetector; + public Map file2HumanMap = [:] + public Map> dupsFilesMap = [:] + public Map> dupsClassMap = [:] + public Map locationMap12 = [:] + public HashSet classes = []; + public HashSet nonUsedLocations; + public HashSet usedLocations; + public HashSet stackTraceIgnoreClassName = new HashSet<>() + public volatile UsedByAnalysis usedByAnalysis; + public final Date startDate = new Date(); + public boolean humanReturnStackTraceElement = true + + AllClasspathAnalysis() { + addClassToStackTraceIgnoreClassName(AddedLocationDetector) + addClassToStackTraceIgnoreClassName(AddFilesToClassLoaderCommon) + addClassToStackTraceIgnoreClassName(CustomObjectHandlerImpl) + addClassToStackTraceIgnoreClassName(AddDirectoryWithFiles) + stackTraceIgnoreClassName.add('org.codehaus.groovy.runtime.') + } + + List easyCalcUsed(){ + addClassesFromCurrentClassLoader() + adder.addClassPathFromURLClassLoader(JrrClassUtils.getCurrentClassLoaderUrl()) + analise(); + Set usedd = getUsedLocationsHuman().keySet() + List sorted = usedd.collect { it.toString() }.sort() + return sorted + + } + + void addClassToStackTraceIgnoreClassName(Class clazz){ + stackTraceIgnoreClassName.add(clazz.getName()) + } + + void addClassesFromCurrentClassLoader() { + addClassesFromClassLoader(AllClasspathAnalysis.getClassLoader()) + } + + void addClassesFromClassLoader(ClassLoader classLoader) { + classes.addAll(DumpLoadedClasses.dumpLoadedClassesNames(classLoader)) + } + + UsedByAnalysis createUsedByAnalysis() { + if (usedByAnalysis == null) { + usedByAnalysis = new UsedByAnalysis(duplicateClassesDetector) + } + return usedByAnalysis; + } + + void analise() { + if (classes.size() == 0) { + throw new Exception("No classes") + } + if (adder.locationMap.size() == 0) { + throw new Exception("No files") + } + dupsFilesMap = adder.findDuplicates() + classesFromLocation = new GetClassesFromLocation() + + adder.locationMap.each { locationMap12.put(it.key, it.value[0]) } + Map> files = classesFromLocation.loadClassesOnLocation(adder.getAddedFiles4()) + duplicateClassesDetector = new DuplicateClassesDetector(classes, files); + duplicateClassesDetector.problemClasses.each { dupsClassMap.put(it.key, getLocations(it.value)) } + resolveHumanLocation() + nonUsedLocations = duplicateClassesDetector.getNonUsedLocations() + usedLocations = duplicateClassesDetector.getUsedLocations() + } + + StackTraceElement resolveLocationByStackTrace(JustStackTrace justStackTrace){ + StackTraceElement[] trace = justStackTrace.getStackTrace() + return trace.toList().find{isGoodStackElement(it)} + } + + boolean isGoodStackElement(StackTraceElement el){ + String find1 = stackTraceIgnoreClassName.find { + return el.getClassName().startsWith(it) + } + return find1==null + } + + HashSet getFilesFromHuman(Collection locations) { + Map reverted = MapUtils.invertMap(file2HumanMap) + List collect1 = locations.collect { + File get1 = reverted.get(it) + if(get1==null){ + throw new Exception("Not found ${it}") + } + return get1 + } + return new HashSet(collect1) + } + + void resolveHumanLocation(){ + ClassPathCalculatorAbstract calculator = createCalculator() + adder.locationMap.each { + Object object = calculator.convertFileToObject(it.key) + file2HumanMap.put(it.key, object) + } + } + + Map getUsedLocationsHuman(){ + return convertListToHuman(usedLocations); + } + + Map getNonUsedLocationsHuman(){ + return convertListToHuman(nonUsedLocations); + } + + Map convertListToHuman(Collection list){ + Map result= [:] + list.each { + Object key1 = file2HumanMap.get(it) + if(key1==null){ + log.info "${it} not found in file2HumanMap" + key1 = it; + } + JustStackTrace justStackTrace = locationMap12.get(it) + Object value2 + if(humanReturnStackTraceElement){ + value2 = resolveLocationByStackTrace(justStackTrace) + }else { + value2 = justStackTrace + } + result.put(key1, value2); + } + return result + } + + ClassPathCalculatorAbstract createCalculator(){ + return new ClassPathCalculatorWithAdder() + } + + List getLocations(List files) { + return files.collect { locationMap12.get(it) } + } + + + Map getFilteredDupsClassMap() { + Map> all1 = dupsClassMap.findAll { return needShowDupClass(it.key) }; + if(humanReturnStackTraceElement){ + Map> rr =[:] + all1.each { + List collect1 = it.value.collect { ss -> resolveLocationByStackTrace(ss) } + rr.put(it.key,collect1) + } + return rr + } + return all1 + } + + Collection getFilteredMissesClasses() { + return new TreeSet(duplicateClassesDetector.missedClasses.findAll { return needShowMissedClass(it) }) + } + + boolean needShowDupClass(String className) { + if (className.contains('$')) { + return false; + } + String startWithFound = dupClassesIgnore.find { it.length() > 0 && className.startsWith(it) } + if (startWithFound != null) { + return false + } + return true + } + + boolean needShowMissedClass(String className) { + if (className.contains('$')) { + return false; + } + String startWithFound = missedIgnore.find { it.length() > 0 && className.startsWith(it) } + if (startWithFound != null) { + return false + } + return true + } + + public List dupClassesIgnore = [] + + public List missedIgnore = [] + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/DumpLoadedClasses.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/DumpLoadedClasses.groovy new file mode 100644 index 00000000..07087e41 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/DumpLoadedClasses.groovy @@ -0,0 +1,85 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.classloader + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.FileRotate; + +import java.util.logging.Logger; + +@CompileStatic +class DumpLoadedClasses { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public File file; + public long periodInSec; + public ClassLoader classLoader1; + + public boolean sort = true; + public volatile boolean needRun = true; + public final Object lock = new Object(); + public Date lastDumped; + public Thread thread; + + DumpLoadedClasses(File dumpToFile, long periodInSec, ClassLoader classLoader1) { + this.file = dumpToFile + this.periodInSec = periodInSec + this.classLoader1 = classLoader1 + if(classLoader1==null){ + throw new NullPointerException('Classloader is null') + } + } + + static DumpLoadedClasses startDumpingClassloader(File dumpToFile, long periodInSec, int rotateCount, ClassLoader classLoader1) { + DumpLoadedClasses dumpLoadedClasses = new DumpLoadedClasses(dumpToFile, periodInSec, classLoader1); + FileRotate.rotateFile(dumpToFile, rotateCount); + dumpLoadedClasses.start(); + return dumpLoadedClasses + + } + + static DumpLoadedClasses startDumpingCurrentClassloader(File dumpToFile, long periodInSec, int rotateCount) { + return startDumpingClassloader(dumpToFile, periodInSec, rotateCount, JrrClassUtils.getCurrentClassLoader()) + } + + static List dumpLoadedClassesNames(ClassLoader cl) { + return new ArrayList(dumpLoadedClasses(cl)).collect { it.getName() } + } + + static List dumpLoadedClasses(ClassLoader cl) { + return JrrClassUtils.getFieldValue(cl, 'classes') as List; + } + + void dumpToFile() { + List classes = dumpLoadedClassesNames(classLoader1) + if (sort) { + classes = classes.sort() + } + PrintWriter writer = file.newPrintWriter() + classes.each { + writer.println(it) + } + writer.flush() + writer.close() + lastDumped = new Date(); + } + + void start() { + Runnable r = { + log.info "class dumper started ${file}" + try { + while (needRun) { + dumpToFile() + synchronized (lock) { + lock.wait(periodInSec * 1000) + } + } + } finally { + log.info "stopped" + } + } + thread = new Thread(r, 'Loaded classes dumper'); + thread.start() + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/DuplicateClassesDetector.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/DuplicateClassesDetector.groovy new file mode 100644 index 00000000..b17f629d --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/DuplicateClassesDetector.groovy @@ -0,0 +1,130 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.classloader + +import groovy.json.JsonOutput +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.util.logging.Logger + +@CompileStatic +class DuplicateClassesDetector { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public HashSet classesNames; + public Map> classesOnLocation = [:]; + public Map> classesOnLocationUsed = [:]; + public Map> classesOnLocationReverse = [:]; + public Map> problemClasses = [:]; + public List missedClasses = []; + public Map foundClasses = [:]; + + DuplicateClassesDetector(HashSet classesNames, Map> classesOnLocation) { + this.classesNames = classesNames + this.classesOnLocation = classesOnLocation + this.classesOnLocation .each { + reverseOneEntry(it.getKey(), it.getValue()); + } + check() + } + + + HashSet convertClassesToLocation(Collection classNames1) { + HashSet result = new HashSet<>() + classNames1.each { + List files = classesOnLocationReverse.get(it) + result.addAll(files) + } + return result; + } + + + HashSet getUsedLocations() { + Map> used = classesOnLocationUsed.findAll { it.value.size() > 0 } + HashSet result = new HashSet<>() + result.addAll (used.keySet()); + return result; + } + + HashSet getNonUsedLocations() { + HashSet result = new HashSet<>() + Map> unused = classesOnLocationUsed.findAll { it.value.size() == 0 } + result.addAll(unused.keySet()) + HashSet files2 = new HashSet(classesOnLocation.keySet()) + files2.removeAll(classesOnLocationUsed.keySet()) + result.addAll(files2) + return result + } + + + protected void reverseOneEntry(File file, List classes) { + classes.each { + List files = classesOnLocationReverse.get(it) + if (files == null) { + files = [] + classesOnLocationReverse.put(it, files) + } + files.add(file) + } + } + + + protected void check() { + classesNames.each { handleOneClass(it) } + classesOnLocation.each { + HashSet classes = new HashSet<>(it.value) + classes.retainAll(classesNames) + classesOnLocationUsed.put(it.key, classes) + } + } + + Map> getClass2FilesMap() { + Map> json1 = new TreeMap<>(); + problemClasses.each { + json1.put(it.key, convertFiles(it.value)) + } + foundClasses.each { + json1.put(it.key, [it.value.getAbsolutePath().replace('\\', '/')]) + } + missedClasses.each { + json1.put(it, []) + } + return json1; + } + + String getClass2FilesJson(){ + String json = JsonOutput.toJson(getClass2FilesMap()); + json = JsonOutput.prettyPrint(json); + return json; + } + + protected List convertFiles(List files) { + return files.collect { it.getAbsolutePath().replace('\\', '/') } + } + + protected void handleOneClass(String oneClass) { + List files = classesOnLocationReverse.get(oneClass) + if (files == null) { + missedClasses.add(oneClass) +// classesOnLocationReverseUsed.put(oneClass,[]) + } else { +// classesOnLocationReverseUsed.put(oneClass,files) + if (files.size() == 1) { + foundClasses.put(oneClass, files[0]) + } else { + problemClasses.put(oneClass, files) + } + } + } + +// HashSet getDependentClasses(String className) { +// File f = foundClasses.get(className); +// if (f == null) { +// List files = problemClasses.get(className) +// f = files[0] +// } +// if (f == null) { +// throw new ClassNotFoundException(className) +// } +// } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/GetClassesFromLocation.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/GetClassesFromLocation.groovy new file mode 100644 index 00000000..a9b64394 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/GetClassesFromLocation.groovy @@ -0,0 +1,69 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.classloader + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.zeroturnaround.zip.ZipEntryCallback +import org.zeroturnaround.zip.ZipUtil; + +import java.util.logging.Logger +import java.util.zip.ZipEntry; + +@CompileStatic +class GetClassesFromLocation { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + Map> loadClassesOnLocation(Collection files) { + Map> classesFromFile = [:] + files.each { + classesFromFile.put(it,handleOneFile(it)); + } + return classesFromFile; + } + + List handleOneFile(File file){ + if (file.isDirectory()) { + return handleDir(file); + } + return handleZip(file) + } + + + + List handleZip(File zipFile) { + List result = [] + ZipEntryCallback zipEntryCallback = new ZipEntryCallback() { + @Override + void process(InputStream inputStream, ZipEntry zipEntry) throws IOException { + String entryName = zipEntry.getName(); + if(entryName.endsWith('.class')) { + String className1 = entryName.replace('/', '.'); + result.add(className1.substring(0,className1.length()-6)) + } + } + } + ZipUtil.iterate(zipFile, zipEntryCallback) + return result + } + + List handleDir(File dir) { + List result = [] + File[] files = dir.listFiles() + files.toList().each { + + String fileName = it.getName() + if (it.isFile()) { + if (fileName.endsWith('.class')) { + String name1 = fileName.substring(0,fileName.length()-6) + result.add(name1) + } + } + if (it.isDirectory()) { + List resTmp = handleDir(it); + result.addAll(resTmp.collect { fileName + '.' + it }) + } + } + return result + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/UsedByAnalysis.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/UsedByAnalysis.groovy new file mode 100644 index 00000000..89d629d7 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/classloader/UsedByAnalysis.groovy @@ -0,0 +1,227 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.classloader + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.classpath.ToFileRef2 +import net.sf.jremoterun.utilities.nonjdk.asmow2.usedclasses.UsedClasses +import org.zeroturnaround.zip.ZipEntryCallback +import org.zeroturnaround.zip.ZipUtil; + +import java.util.logging.Logger +import java.util.zip.ZipEntry; + +@CompileStatic +class UsedByAnalysis { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public DuplicateClassesDetector det; + + public Map> classToUsedInFiles = [:]; + public Map> usesClassesFromClass = [:]; + public Map> usesClassesFromLocation = [:]; + + UsedByAnalysis(DuplicateClassesDetector det) { + this.det = det + init() + } + + + protected void init() { + det.classesOnLocationUsed.keySet().each { usesClassesFromLocation.put(it, getDependentClasses(it)) } + usesClassesFromLocation.each { handleRevrseUsed(it.key, it.value) } + } + + + HashSet getUsedByClassesComplex(File location) { + location = location.getCanonicalFile().getAbsoluteFile() + List classes12 = det.classesOnLocation.get(location) + if (classes12 == null) { + throw new Exception("Location not found ${location}") + } + Set classesOnLocation = det.classesOnLocationUsed.get(location) + HashSet result = [] + if (classesOnLocation != null) { + classesOnLocation.each { + List files = classToUsedInFiles.get(it) + if (files != null) { + result.addAll(files) + } + } + result.remove(location) + } + return result; + } + + HashSet getUsedByClassesComplex(Collection locations) { + locations = locations.collect { it.getCanonicalFile().getAbsoluteFile() } + HashSet result = new HashSet<>() + locations.each { + result.addAll(getUsedByClassesComplex(it)) + } + result.removeAll(locations) + return result + } + + +// HashSet getDependentClassesEasyMaven(List locations) { +// List collect1 = locations.collect { it.resolveToFile() } +// return getUsedByClassesComplex(collect1) +// } + + HashSet getDependentClassesEasy(Collection locations) { + locations = locations.collect { it.getCanonicalFile().getAbsoluteFile() } + HashSet result = new HashSet<>() + locations.each { + List classes12 = det.classesOnLocation.get(it) + if (classes12 == null) { + throw new Exception("Location not found ${it}") + } + Set classes = usesClassesFromLocation.get(it) + if (classes != null) { + result.addAll(classes) + } + } + HashSet result2 = new HashSet<>(result.collect { it.replace('/', '.') }) + locations.each { + Set classNamesOnLocationUsed = det.classesOnLocationUsed.get(it) + if (classNamesOnLocationUsed != null) { + result2.removeAll(classNamesOnLocationUsed) + } + } + result2.retainAll(det.classesNames) + return result2 + } + + + protected void handleRevrseUsed(File location, Set usesInThisLocation) { + List usesInThisLocation2 = new ArrayList<>(usesInThisLocation) + usesInThisLocation2.retainAll(det.classesNames); + usesInThisLocation2.each { + List usedIn = classToUsedInFiles.get(it) + if (usedIn == null) { + usedIn = [] + classToUsedInFiles.put(it, usedIn) + } + usedIn.add(location) + } + + } + + +// HashSet getDependentClassesR(List locations) { +// return getDependentClasses(locations.collect {it.resolveToFile()}) +// } +// + + + HashSet getDependentClassesHumanFile(String toAnalize, int maxDepth) { + return det.convertClassesToLocation(getDependentClassesHuman(toAnalize, maxDepth)); + } + + HashSet getDependentClassesHuman(String toAnalize, int maxDepth) { + HashSet needed = new HashSet<>() + HashSet skipped = new HashSet<>() + getDependentClasses(toAnalize, needed, skipped, maxDepth); + return needed; + } + + protected void getDependentClasses(String toAnalize, HashSet needed, HashSet skipped, int maxDepth) { + if (!det.classesNames.contains(toAnalize)) { + throw new Exception("Not found : ${toAnalize}") + } + needed.add(toAnalize); + List files = det.classesOnLocationReverse.get(toAnalize); + if (files == null || files.size() == 0) { + throw new Exception("not class on location : ${toAnalize}") + } + String classNameToPath = convertClassNameToPath(toAnalize) + File location = files[0] + HashSet result = new HashSet<>() + if (location.isDirectory()) { + File classFile = location.child(classNameToPath) + if (!classFile.exists()) { + throw new FileNotFoundException(classFile.getAbsolutePath()) + } + HashSet usedTypes = UsedClasses.remapClassNoRedefine(classFile.bytes).usedTypes + result.addAll(usedTypes) + } else { + assert location.isFile() + ZipEntryCallback zipEntryCallback = new ZipEntryCallback() { + @Override + void process(InputStream inputStream, ZipEntry zipEntry) throws IOException { + if (zipEntry.getName() == classNameToPath) { + byte[] bytes = inputStream.bytes + HashSet usedTypes = UsedClasses.remapClassNoRedefine(bytes).usedTypes + result.addAll(usedTypes) + } + } + } + ZipUtil.iterate(location, zipEntryCallback) + } + HashSet result2 = new HashSet<>(result.collect { it.replace('/', '.') }) + result2.each { + if (needed.contains(it)) { + + } else { + if (det.classesNames.contains(it)) { + needed.add(it); + if (maxDepth != 0) { + getDependentClasses(it, needed, skipped, maxDepth - 1); + } + } else { + skipped.add(it); + } + } + } + } + + protected HashSet getDependentClasses(File location) { + location = location.getCanonicalFile().getAbsoluteFile() + Set classNamesOnLocationUsed = det.classesOnLocationUsed.get(location) + if (det.classesOnLocationUsed == null) { + throw new Exception("location not found ${location}") + } + if (classNamesOnLocationUsed.size() == 0) { + return new HashSet() + } + HashSet classNamesOnLocationUsed22 = new HashSet<>(classNamesOnLocationUsed.collect { convertClassNameToPath(it) }) + HashSet result = new HashSet<>() + if (location.isDirectory()) { + classNamesOnLocationUsed22.each { + String fileName = it; + File classFile = location.child(fileName) + if (!classFile.exists()) { + throw new FileNotFoundException(classFile.getAbsolutePath()) + } + HashSet usedTypes = UsedClasses.remapClassNoRedefine(classFile.bytes).usedTypes + usesClassesFromClass.put(fileName, usedTypes) + result.addAll(usedTypes) + + } + } else { + assert location.isFile() + ZipEntryCallback zipEntryCallback = new ZipEntryCallback() { + @Override + void process(InputStream inputStream, ZipEntry zipEntry) throws IOException { + if (classNamesOnLocationUsed22.contains(zipEntry.getName())) { + byte[] bytes = inputStream.bytes + HashSet usedTypes = UsedClasses.remapClassNoRedefine(bytes).usedTypes + usesClassesFromClass.put(zipEntry.getName(), usedTypes) + result.addAll(usedTypes) + } + } + } + ZipUtil.iterate(location, zipEntryCallback) + } + HashSet result2 = new HashSet<>(result.collect { it.replace('/', '.') }) + result2.removeAll(classNamesOnLocationUsed) + return result2 + + } + + static String convertClassNameToPath(String className) { + return className.replace('.', '/') + '.class'; + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/AddFilesToClassLoaderGroovyDownloader.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/AddFilesToClassLoaderGroovyDownloader.groovy index 3d0d5041..7400bb82 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/AddFilesToClassLoaderGroovyDownloader.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/AddFilesToClassLoaderGroovyDownloader.groovy @@ -8,6 +8,7 @@ import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.mdep.ivy.IvyDepResolverException +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import org.apache.commons.io.FileUtils import java.util.logging.Level @@ -69,12 +70,12 @@ class AddFilesToClassLoaderGroovyDownloader extends AddFilesToClassLoaderGroovy addedFiles2.findAll { it != null }.each { JrrUtilities.checkFileExist(it) if (it.file) { - FileUtils.copyFileToDirectory(it, toFolder) + FileUtilsJrr.copyFileToDirectory(it, toFolder) } else { File toFolder2 = new File(toFolder, "classes") toFolder2.mkdir() assert toFolder2.exists() - FileUtils.copyDirectory(it, toFolder2) + FileUtilsJrr.copyDirectory(it, toFolder2) } } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrConfigGenerator.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrConfigGenerator.groovy index 8b2fae08..1a9eecd3 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrConfigGenerator.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrConfigGenerator.groovy @@ -43,7 +43,7 @@ class JrrConfigGenerator implements ClassNameSynonym{ void generateConfig(boolean raw, boolean userConfig, boolean overrideFile) { String s = configText if (s == null) { - s = readText('jrrgroovyconfig_raw.groovy') + s = readText(JrrStarterConstatnts.rawConfigFileName) } File jrrConfigDir = getJrrConfigDir() String className3 @@ -65,7 +65,7 @@ class JrrConfigGenerator implements ClassNameSynonym{ f = JrrStarterConstatnts.configFileName as File } } - String fileContent = s.replace('jrrgroovyconfig_raw', className3) + String fileContent = s.replace(JrrStarterConstatnts.rawConfigFileName, className3) if (f.exists() && !overrideFile) { throw new IOException("file exist : ${f.absolutePath}") } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrConsoleDecompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrConsoleDecompiler.groovy index 08705969..81f94014 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrConsoleDecompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrConsoleDecompiler.groovy @@ -1,6 +1,7 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.console import com.github.javaparser.JavaParser +import com.github.javaparser.ParseResult import com.github.javaparser.ast.CompilationUnit import com.github.javaparser.ast.body.MethodDeclaration import com.github.javaparser.ast.body.TypeDeclaration @@ -21,21 +22,21 @@ class JrrConsoleDecompiler implements ClassNameSynonym{ private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - void f1(File from, File toDir) { - String[] args = [from.absolutePath, toDir.absolutePath] + void decompileDirect(File from, File toDir) { + String[] args = [from.getAbsolutePath(), toDir.getAbsolutePath()] ConsoleDecompiler.main(args) } - void decompile(File jarFile, String className) { - decompile(jarFile, className, [:]) + void decompile(String className,File jarFile) { + decompile(className, [:],jarFile) } void decompile2(String className) { - decompile(findJar(className), className) + decompile(className,findJar(className)) } void decompile2(String className, String methodName, int argCount) { - decompile(findJar(className), className, methodName, argCount) + decompile(className, methodName, argCount,findJar(className)) } File findJar(String className) { @@ -57,9 +58,10 @@ class JrrConsoleDecompiler implements ClassNameSynonym{ } - void decompile(File jarFile, String className, Map options) { + void decompile(String className, Map options, File jarFile) { FernflowerDecompiler2 fernflowerDecompiler = new FernflowerDecompiler2(options) fernflowerDecompiler.addFiles.addRtJar() + fernflowerDecompiler.addFiles.addJfrJarsIfExists() String decompile = fernflowerDecompiler.decompile(jarFile, className) log.info "${decompile}" } @@ -68,10 +70,10 @@ class JrrConsoleDecompiler implements ClassNameSynonym{ AddFileToClassloaderDummy fileToClassloaderDummy = new AddFileToClassloaderDummy() fileToClassloaderDummy.add mavenId File file = fileToClassloaderDummy.addedFiles2[0] - decompile(file, className, methodName, argCounts) + decompile(className, methodName, argCounts,file) } - void decompile(File jarFile, String className, String methodName, int argCounts) { + void decompile(String className, String methodName, int argCounts,File jarFile) { FernflowerDecompiler2 fernflowerDecompiler = new FernflowerDecompiler2() String decompile = fernflowerDecompiler.decompile(jarFile, className) f3(decompile, methodName, argCounts) @@ -79,7 +81,8 @@ class JrrConsoleDecompiler implements ClassNameSynonym{ void f3(String classContent, String methodName, int argCounts) { assert classContent != null - CompilationUnit cu = JavaParser.parse(classContent); +// CompilationUnit cu = JavaParser.parse(classContent); + CompilationUnit cu = new JavaParser().parse(classContent).result.get(); int size = cu.getTypes().size() if (size == 0) { throw new IllegalStateException("no types found : ${classContent}") diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrIdeaGenerator.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrIdeaGenerator.groovy index 5c3e1976..12086bc6 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrIdeaGenerator.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrIdeaGenerator.groovy @@ -5,8 +5,10 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.groovystarter.ClassNameSynonym import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.classpath.CustomObjectHandlerImpl import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs2 import net.sf.jremoterun.utilities.nonjdk.compile.IdeaInitPluginCompiler import net.sf.jremoterun.utilities.nonjdk.compile.IdeaPluginCompiler import net.sf.jremoterun.utilities.nonjdk.compile.JrrUtilsCompiler @@ -25,7 +27,7 @@ class JrrIdeaGenerator implements ClassNameSynonym { File ideaPlugin = compileAndPrepare(ideaDir) File ideaPluginConfigs = ideaPLuginDir.child('config/plugins') assert ideaPLuginDir.exists() - FileUtils.copyDirectoryToDirectory(ideaPlugin, ideaPluginConfigs) + FileUtilsJrr.copyDirectoryToDirectory(ideaPlugin, ideaPluginConfigs) updateVmOptions(ideaPLuginDir) log.info "plugin created in ${ideaPluginConfigs}" } @@ -37,9 +39,9 @@ class JrrIdeaGenerator implements ClassNameSynonym { File pluginDir2 = compiler.client.ifDir.child("build/${pluginName}") File pluginDir = pluginDir2.child("lib") pluginDir.mkdirs() - FileUtils.copyFileToDirectory(JrrStarterJarRefs.jremoterun.resolveToFile(), pluginDir) - FileUtils.copyFileToDirectory(JrrStarterJarRefs.jrrassist.resolveToFile(), pluginDir) - FileUtils.copyFileToDirectory(IdeaInitPluginCompiler.getJrrUtilsJar(), pluginDir) + FileUtilsJrr.copyFileToDirectory(JrrStarterJarRefs2.jremoterun.resolveToFile(), pluginDir) + FileUtilsJrr.copyFileToDirectory(JrrStarterJarRefs2.jrrassist.resolveToFile(), pluginDir) + FileUtilsJrr.copyFileToDirectory(IdeaInitPluginCompiler.getJrrUtilsJar(), pluginDir) File pluginJar = pluginDir.child("${pluginName}.jar") File metaInf = compiler.client.ifDir.child('resources/idea/META-INF') compiler.testUpdateIdeaJar2(pluginJar, metaInf) diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrJarRunner.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrJarRunner.groovy new file mode 100644 index 00000000..9ed87d1a --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrJarRunner.groovy @@ -0,0 +1,80 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.console + + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.ObjectWrapper; +import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams; +import org.apache.commons.io.IOUtils; +import org.zeroturnaround.zip.ZipEntryCallback; +import org.zeroturnaround.zip.ZipUtil; + +import java.util.logging.Logger +import java.util.zip.ZipEntry + +@CompileStatic +class JrrJarRunner implements Runnable { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static String mainClassMajicName = 'Main-Class:' + + @Override + void run() { + String argg = GroovyMethodRunnerParams.gmrp.args[0] + File file1 = argg as File + if (!file1.exists()) { + throw new FileNotFoundException(file1.getAbsolutePath()) + } + run3(file1, GroovyMethodRunnerParams.gmrp) + + } + + void run3(File f, GroovyMethodRunnerParams gmrp) { + String manifestFromJar = extractManifestFromJar(f) + String mainClass = findMainClassFromManifest(manifestFromJar) + log.info "mainClass : ${mainClass}" + gmrp.addFilesToClassLoader.addF f + gmrp.args.remove(0) + gmrp.args.add (0,'main') + gmrp.args.add(0,mainClass) + + } + + + String findMainClassFromManifest(String manifest) { + List lines = manifest.readLines() + String linee = lines.find { it.startsWith(mainClassMajicName) } + if (linee == null) { + throw new Exception("${mainClassMajicName} not found in : ${manifest}") + } + linee = linee.replace(mainClassMajicName, '') + return linee.trim() + } + + String extractManifestFromJar(File f) { + ObjectWrapper res = new ObjectWrapper<>(null) + ZipEntryCallback zec = new ZipEntryCallback() { + @Override + void process(InputStream inputStream, ZipEntry zipEntry) throws IOException { + if (zipEntry.getName() == 'META-INF/MANIFEST.MF') { + byte[] arrayRes = IOUtils.toByteArray(inputStream) + String s2 = new String(arrayRes) + if (res.getObject() != null) { + throw new Exception("Jar has 2 manifests : \n${res.object}\n 2nd: \n${s2}") + } + res.setObject(s2) + } + + } + }; + ZipUtil.iterate(f, zec) + String object = res.getObject() + if (object == null) { + throw new Exception('manifest not found') + } +// log.info "${object}" + return object.trim() + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrSvnConsole.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrSvnConsole.groovy new file mode 100644 index 00000000..be98d68e --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/JrrSvnConsole.groovy @@ -0,0 +1,15 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.console + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.groovystarter.ClassNameSynonym +import org.tmatesoft.svn.cli.svn.SVN; + +import java.util.logging.Logger; + +@CompileStatic +class JrrSvnConsole extends SVN implements ClassNameSynonym { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/auxp/ConsoleCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/auxp/ConsoleCompiler.groovy index 6dca652e..20f270e5 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/auxp/ConsoleCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/auxp/ConsoleCompiler.groovy @@ -5,6 +5,7 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.AddFilesToUrlClassLoaderGroovy import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import net.sf.jremoterun.utilities.nonjdk.compile.GenericCompiler import net.sf.jremoterun.utilities.nonjdk.compiler3.GroovyCompiler @@ -13,7 +14,7 @@ import net.sf.jremoterun.utilities.nonjdk.methodrunner.AuxMethodRunner import java.util.logging.Logger @CompileStatic -class ConsoleCompiler implements Runnable{ +class ConsoleCompiler implements Runnable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); @@ -21,19 +22,19 @@ class ConsoleCompiler implements Runnable{ void run() { GroovyMethodRunnerParams gmrp = GroovyMethodRunnerParams.gmrp List args = gmrp.args - if(args.size()<2){ + if (args.size() < 2) { throw new IllegalArgumentException("too low arguments, needed : ") } - List inDirs = args[0].tokenize(',').collect {it as File} - inDirs.each {assert it.exists()} - inDirs = inDirs.collect {it.canonicalFile.absoluteFile} - assert inDirs.size()>0 + List inDirs = args[0].tokenize(',').collect { it as File } + inDirs.each { assert it.exists() } + inDirs = inDirs.collect { it.canonicalFile.absoluteFile } + assert inDirs.size() > 0 File outDir = args[1] as File outDir.mkdirs() assert outDir.exists() outDir = outDir.canonicalFile.absoluteFile log.info "compiling : ${inDirs}" - GenericCompiler genericCompiler = new GenericCompiler(){ + GenericCompiler genericCompiler = new GenericCompiler() { @Override void prepare() { @@ -44,12 +45,12 @@ class ConsoleCompiler implements Runnable{ } genericCompiler.params.outputDir = outDir AddFilesToUrlClassLoaderGroovy adder = genericCompiler.client.adder - adder.add LatestMavenIds.eclipseJavaCompiler - adder.add LatestMavenIds.eclipseJavaAstParser + adder.add(CustObjMavenIds.eclipseJavaCompiler) + adder.add(CustObjMavenIds.eclipseJavaAstParser) adder.addFilesFromGmrp() genericCompiler.compile() inDirs.each { - CopyResourcesFromDirToDir.copyResourcesFromDirToDir(it,outDir) + CopyResourcesFromDirToDir.copyResourcesFromDirToDir(it, outDir) } gmrp.addFilesToClassLoader.addFile outDir args.remove(0) diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/auxp/CopyResourcesFromDirToDir.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/auxp/CopyResourcesFromDirToDir.groovy index 3060ac5b..291ac0bd 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/auxp/CopyResourcesFromDirToDir.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/console/auxp/CopyResourcesFromDirToDir.groovy @@ -2,6 +2,7 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.console.auxp import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import org.apache.commons.io.FileUtils import org.apache.commons.io.FilenameUtils @@ -28,7 +29,7 @@ class CopyResourcesFromDirToDir { if (extension != null && (extension == 'groovy' || extension == 'java')) { } else { - FileUtils.copyFile(it, destFile2) + FileUtilsJrr.copyFile(it, destFile2) } } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/SrcDirFinder.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/SrcDirFinder.groovy new file mode 100644 index 00000000..e25edc93 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/helpers/SrcDirFinder.groovy @@ -0,0 +1,57 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.helpers + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class SrcDirFinder { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + /** + * Find all dirs with pattern : 'child/childDirs/' + */ + static List findSourcesSimple(File baseDir, String childDirs) { + assert baseDir.exists() + assert baseDir.isDirectory() + //childDirs = 'src/main/java' + List files = baseDir.listFiles().toList() + files = files.findAll { it.isDirectory() } + files = files.collect { it.child(childDirs) } + files = files.findAll { it.exists() } + if (files.size() == 0) { + throw new Exception("No source found in ${baseDir}, child dirs = ${childDirs}") + } + return files; + } + + + /** + * Find all dirs which have classes or files inside + */ + static List findSourcesByPackageWithCheck(File baseDir, String samplePackage, int depth) { + List result = findSourcesByPackage(baseDir, samplePackage, depth) + if (result.size() == 0) { + throw new Exception("No source found in ${baseDir}, depth = ${depth}, sample : ${samplePackage} ") + } + } + + static List findSourcesByPackage(File baseDir, String samplePackage, int depth) { + assert baseDir.exists() + assert baseDir.isDirectory() + //childDirs = 'src/main/java' + List files = baseDir.listFiles().toList() + List allDirs = files.findAll { it.isDirectory() } + List matched = allDirs.findAll { it.child(samplePackage).exists() } + if (depth > 0) { + int newDepth = depth - 1 + allDirs.each { + matched.addAll(findSourcesByPackage(it, samplePackage, newDepth)) + } + } + return matched; + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/refs2/EclipseLatest.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/refs2/EclipseLatest.groovy new file mode 100644 index 00000000..8c913fde --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/refs2/EclipseLatest.groovy @@ -0,0 +1,25 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.refs2 + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.nonjdk.classpath.search.MavenResponseParser +import net.sf.jremoterun.utilities.nonjdk.classpath.search.MavenSearch; + +import java.util.logging.Logger; + +@CompileStatic +class EclipseLatest { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static String eclipseGroupId = 'org.eclipse.platform' + + static List findLatestEclipseMavenIds() { + MavenSearch mavenSearch = new MavenSearch(); + Map raw = mavenSearch.findMavenIdsAllArtifactsWithGroupIdRaw(eclipseGroupId, 500); + List response2 = new MavenResponseParser().parseAllWithGroupLatestResponse2(raw); + return response2; + + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClassPathTesterHelper.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClassPathTesterHelper.groovy index 385ad67d..e449517f 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClassPathTesterHelper.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClassPathTesterHelper.groovy @@ -10,18 +10,31 @@ import net.sf.jremoterun.utilities.classpath.MavenCommonUtils import net.sf.jremoterun.utilities.classpath.MavenId import net.sf.jremoterun.utilities.classpath.MavenIdContains import net.sf.jremoterun.utilities.nonjdk.classpath.UrlCLassLoaderUtils2 +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollectorI +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollectorIThrowImmediate +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemFoundException +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemHelper import java.util.logging.Logger +@Deprecated @CompileStatic -public abstract class ClassPathTesterHelper implements Runnable { +public abstract class ClassPathTesterHelper extends ClassPathTesterHelper2 implements Runnable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - ClassLoader currentClassLoader = ClassPathTesterHelper.getClassLoader(); +// ClassLoader currentClassLoader = JrrClassUtils.getCurrentClassLoader() static MavenCommonUtils mavenCommonUtils = new MavenCommonUtils(); + ClassPathTesterHelper(ProblemCollectorI problemCollector) { + super(problemCollector) + } + + ClassPathTesterHelper() { + super(new ProblemCollectorIThrowImmediate()) + } + @Override public final void run() { try { @@ -32,136 +45,63 @@ public abstract class ClassPathTesterHelper implements Runnable { } } - public static void checkClassInstanceOf(Object object, Class instanceOf) throws Exception { - Class aClass = object.getClass(); - URL location = JrrUtils.getClassLocation(aClass); - String msg = instanceOf.getName() + " class : " + aClass.getName() + " , location " + location; - if (aClass != instanceOf) { - throw new Exception(msg); - } -// log.info(msg); - } - -// public void checkNoSuchClass(ClRef className) throws Exception { -// checkNoSuchClass(className.className) -// } - public void checkNoSuchClass(ClRef className) throws Exception { - checkNoSuchClass(className, currentClassLoader); + static void checkClassInstanceOf(Object object, Class instanceOf) { + createClassPathTesterHelper2().checkClassInstanceOf5(object,instanceOf) } + static void checkTheSameClassLoader(Class clazz, ClassLoader classLoader) { - ClassLoader classLoader1 = clazz.getClassLoader() - if (classLoader1 != classLoader) { - if (classLoader1 == null) { - throw new Exception("Class ${clazz.name} loaded by boot classloader"); - } - throw new Exception("Class ${clazz.name} loaded by diff classloader ${classLoader1.class.name} ${classLoader1}"); - } + createClassPathTesterHelper2().checkTheSameClassLoader5(clazz,classLoader) } - public static void checkNoSuchClass(ClRef className, ClassLoader classLoader) throws Exception { - try { - Class clazz = classLoader.loadClass(className.className); - checkTheSameClassLoader(clazz, classLoader) - File location = UrlCLassLoaderUtils.getClassLocation(clazz); - throw new Exception("${className.className} is present : ${location}"); - } catch (ClassNotFoundException e) { - - } + public static void checkNoSuchClass(ClRef className, ClassLoader classLoader) { + createClassPathTesterHelper2().checkNoSuchClass5(className,classLoader) } - public static void checkFieldExists(Class clazz, String field) throws Exception { - try { - JrrClassUtils.findField(clazz, field); - } catch (NoSuchFieldException e) { - File location = UrlCLassLoaderUtils.getClassLocation(clazz); - throw new Exception("In class " + clazz.getName() + " field not found " + field + " , location " + location); - } + public static void checkFieldExists(Class clazz, String field) { + createClassPathTesterHelper2().checkFieldExists5(clazz,field) } static void checkClassOnce(Class clazz, MavenIdContains mavenId) { - checkClassOnce(clazz, mavenCommonUtils.findMavenOrGradle(mavenId.getM())) + createClassPathTesterHelper2().checkClassOnce5(clazz, mavenId.getM()) } static void checkClassOnce(Class clazz) { - List files = UrlCLassLoaderUtils2.getClassLocationAll2(clazz); - assert files.size() == 1 + createClassPathTesterHelper2().checkClassOnce5(clazz) } + @Deprecated static void checkClassNotFromPathNoEx(Class clazz, File notPath) { try { checkClassNotFromPath(clazz, notPath) + } catch (ProblemFoundException e) { + JrrUtilities.showException(e.getMessage(), e) } catch (UndesiredClassLocationException e) { JrrUtilities.showException(e.getMessage(), e) } } static void checkClassNotFromPath(Class clazz, File notPath) { - assert notPath.exists() - List files = UrlCLassLoaderUtils2.getClassLocationAll2(clazz); - switch (files.size()) { - case 0: - throw new Exception("class was not found : ${clazz.name}") - case 1: - File actualFile = files[0] - if (actualFile == null) { - throw new Exception("actual file is null for ${clazz}") - } - actualFile = actualFile.canonicalFile.absoluteFile - String actualPathS = actualFile.absolutePath; - String notPathS = notPath.absolutePath - if (actualPathS == notPathS) { - throw new UndesiredClassLocationException("Class ${clazz.getName()} from undesired path : ${notPath}") - } - break; - default: - files = files.collect { it.canonicalFile } - throw new Exception("found many path ${files.size()} : ${files.join(' , ')}") - } + createClassPathTesterHelper2().checkClassNotFromPath5(clazz,notPath) } static void checkClassOnce(Class clazz, File expectedFile) { - if (expectedFile == null) { - throw new Exception("expectedFile is null for ${clazz}") - } - if (!expectedFile.exists()) { - throw new Exception("expectedFile ${expectedFile} not exists for ${clazz}") - } - expectedFile = expectedFile.canonicalFile.absoluteFile - List files = UrlCLassLoaderUtils2.getClassLocationAll2(clazz); - switch (files.size()) { - case 0: - throw new Exception("class was not found : ${clazz.name}") - case 1: - File actualFile = files[0] - if (actualFile == null) { - throw new Exception("actual file is null for ${clazz} ${expectedFile}") - } - actualFile = actualFile.canonicalFile.absoluteFile - assert actualFile == expectedFile - break; - default: - files = files.collect { it.canonicalFile } - throw new Exception("found many path ${files.size()} : ${files.join(' , ')}") - } + createClassPathTesterHelper2().checkClassOnce5(clazz,expectedFile) } - public static void checkClassLocation(Class clazz, MavenId mavenId) throws Exception { - checkClassLocation(clazz, mavenCommonUtils.findMavenOrGradle(mavenId)); + public static void checkClassLocation(Class clazz, MavenId mavenId) { + createClassPathTesterHelper2().checkClassLocation5(clazz,mavenId) } - public static void checkClassLocation(Class clazz, File locationExpected) throws Exception { - File currentLocation = UrlCLassLoaderUtils.getClassLocation(clazz); - if (locationExpected != currentLocation) { - throw new Exception("class " + clazz.getName() + " location strange " + currentLocation); - } + public static void checkClassLocation(Class clazz, File locationExpected) { + createClassPathTesterHelper2().checkClassLocation5(clazz,locationExpected) } - public abstract void runImpl() throws Exception; + public abstract void runImpl(); } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClassPathTesterHelper2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClassPathTesterHelper2.groovy new file mode 100644 index 00000000..f05baf82 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClassPathTesterHelper2.groovy @@ -0,0 +1,313 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.tester + +import groovy.transform.CompileStatic +import net.sf.jremoterun.JrrUtils +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import net.sf.jremoterun.utilities.UrlCLassLoaderUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.classpath.MavenCommonUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenIdContains +import net.sf.jremoterun.utilities.nonjdk.classpath.UrlCLassLoaderUtils2 +import net.sf.jremoterun.utilities.nonjdk.problemchecker.JustStackTrace +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollectorI +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollectorIThrowImmediate +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemHelper + +import java.util.logging.Logger + +@CompileStatic +class ClassPathTesterHelper2 { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ClassLoader currentClassLoader = ClassPathTesterHelper2.getClassLoader(); + + static MavenCommonUtils mavenCommonUtils = new MavenCommonUtils(); + + ProblemCollectorI problemCollector + + ClassPathTesterHelper2(ProblemCollectorI problemCollector) { + this.problemCollector = problemCollector + } + + void checkClassInstanceOf5(Object object, Class instanceOf) { + Class aClass = object.getClass(); + URL location = JrrUtils.getClassLocation(aClass); + String msg = instanceOf.getName() + " class : " + aClass.getName() + " , location " + location; + if (aClass != instanceOf) { + addProblem(instanceOf.name, msg); + } +// log.info(msg); + } + +// public void checkNoSuchClass(ClRef className){ +// checkNoSuchClass(className.className) +// } + + + static ClassPathTesterHelper2 createClassPathTesterHelper2(){ + return new ClassPathTesterHelper2(new ProblemCollectorIThrowImmediate()); + } + + void checkNoSuchClass(ClRef className) { + checkNoSuchClass5(className, currentClassLoader); + } + + + Class checkClassLoaded(ClRef className, ClassLoader classLoader) { + try { + Class clazz = className.loadClass(classLoader) + return clazz + } catch (Throwable e) { + addProblem2(className.className, "failed load class : ${className}", e) + return null + } + } + + + boolean checkTheSameClassLoader5(Class clazz, ClassLoader classLoader) { + ClassLoader classLoader1 = clazz.getClassLoader() + if (classLoader1 != classLoader) { + if (classLoader1 == null) { + addProblem(clazz.name, "Class ${clazz.name} loaded by boot classloader"); + } + addProblem(clazz.name, "Class ${clazz.name} loaded by diff classloader ${classLoader1.class.name} ${classLoader1}"); + return false + } + return true + + } + + + void checkClassLoaderHierarchy(Class clazz, ClassLoader parentClassLoader, ClassLoader childClassLoader) { + if (checkTheSameClassLoader5(clazz, parentClassLoader)) { + checkNotSameClassLoader5(clazz, childClassLoader) + } + } + + + void checkNotSameClassLoader5(ClRef clazz, ClassLoader classLoader) { + Class clazz1 = checkClassLoaded(clazz, classLoader) + if (clazz1 != null) { + checkNotSameClassLoader5(clazz1, classLoader) + } + } + + void checkNotSameClassLoader5(Class clazz, ClassLoader classLoader) { + Class clazz1 = classLoader.loadClass(clazz.name) + ClassLoader classLoader1 = clazz1.getClassLoader() + if (classLoader1 == classLoader) { + addProblem(clazz.name, "Class ${clazz.name} loaded by unwanted classloader ${classLoader1.class.name} ${classLoader1}"); + } + } + + URL checkResourceExists(String resource) { + URL resourceUrl = JrrClassUtils.currentClassLoader.getResource(resource) + if (resourceUrl == null) { + addProblem(null, "Resource not found : ${resource}") + } + return resourceUrl; + } + + URL checkResourceExistsOnce(String resource) { + List resourceUrls = JrrClassUtils.currentClassLoader.getResources(resource).toList() + int size = resourceUrls.size() + if (size == 0) { + addProblem(null, "Resource not found : ${resource}") + return null + } + if (size > 1) { + addProblem(null, "Resource found many : ${resourceUrls}") + return null + } + return resourceUrls[0] + } + + void checkResourceExistsOnceAndLocation(String resource, URL location) { + URL resourceUrl = checkResourceExistsOnce(resource) + if (resourceUrl != null) { + if (resourceUrl != location) { + addProblem(null, "Resource ${resource} location not matched : ${location}") + } + } + } + + void checkResourceLocation(String resource, URL location) { + URL resourceUrl = checkResourceExists(resource) + if (resourceUrl != null) { + if (resourceUrl != location) { + addProblem(null, "Resource ${resource} location not matched : ${location}") + } + } + } + + void checkFileExist(File f) { + if (!f.exists()) { + addProblem(null, "File not found : ${f}") + } + } + + void checkNoSuchClass5(ClRef className, ClassLoader classLoader) { + try { + Class clazz = classLoader.loadClass(className.className); + checkTheSameClassLoader5(clazz, classLoader) + File location = UrlCLassLoaderUtils.getClassLocation(clazz); + addProblem(clazz.name, "${className.className} is present : ${location}"); + } catch (ClassNotFoundException e) { + + } + } + + void checkFieldExists5(Class clazz, String field) { + try { + JrrClassUtils.findField(clazz, field); + } catch (NoSuchFieldException e) { + File location = UrlCLassLoaderUtils.getClassLocation(clazz); + addProblem2(clazz.name, "In class " + clazz.getName() + " field not found " + field + " , location " + location, e); + } + } + + + void checkClassOnce5(Class clazz, MavenIdContains mavenId) { + checkClassOnce5(clazz, mavenCommonUtils.findMavenOrGradle(mavenId.getM())) + } + + void checkClassOnce5(Class clazz) { + List files = UrlCLassLoaderUtils2.getClassLocationAll2(clazz); + if (files.size() == 0) { + addProblem(clazz.name, "class not found : ${clazz.getName()}") + } + if (files.size() > 1) { + addProblem(clazz.name, "found many files for class ${clazz.getName()} : ${files}") + } + } + + public static long lastModifiedCacheMax = 3600_000*24*7; + + void checkClassPresentInCache(Class clazz, File cachePath) { + File classInCache = cachePath.child(clazz.getName().replace('.', '/') + '.class') + if (classInCache.exists()) { + long lastModified1 = classInCache.lastModified() + long lastModifiedDiff = System.currentTimeMillis() - lastModified1 + if(lastModifiedDiff>lastModifiedCacheMax){ + addProblem(clazz.getName(), "Class ${clazz.getName()} in cache too old : ${new Date(lastModified1)}") + } + List all2 = UrlCLassLoaderUtils2.getClassLocationAll2(clazz) + if (all2.size() == 0) { + addProblem(clazz.getName(), "Failed find class ${clazz.getName()}") + } else { + if (cachePath.isChildFile(all2.first())) { + addProblem(clazz.getName(), "Class ${clazz.getName()} used from cache") + } else { + File found = all2.find { cachePath.isChildFile(it) } + if (found == null) { + addProblem(clazz.getName(), "Class ${clazz.getName()} not found in cache") + } + } + } + } else { + addProblem(clazz.getName(), "Class not in cache : ${classInCache}"); + } + } + + + void checkClassNotFromPath5(Class clazz, File notPath) { + if (!notPath.exists()) { + addProblem(clazz.name, "File not found : ${notPath}") + } + List files = UrlCLassLoaderUtils2.getClassLocationAll2(clazz); + switch (files.size()) { + case 0: + throw new Exception("class was not found : ${clazz.name}") + case 1: + File actualFile = files[0] + if (actualFile == null) { + throw new Exception("actual file is null for ${clazz}") + } + actualFile = actualFile.canonicalFile.absoluteFile + String actualPathS = actualFile.absolutePath; + String notPathS = notPath.absolutePath + if (actualPathS == notPathS) { + addProblem2(clazz.name, "Class ${clazz.getName()} from undesired path : ${notPath}", new UndesiredClassLocationException("Class ${clazz.getName()} from undesired path : ${notPath}")) + } + break; + default: + files = files.collect { it.canonicalFile } + addProblem(clazz.name, "found many path ${files.size()} : ${files.join(' , ')}") + } + + } + + void checkClassOnce5(Class clazz, File expectedFile) { + if (expectedFile == null) { + throw new Exception("expectedFile is null for ${clazz}") + } + if (!expectedFile.exists()) { + throw new Exception("expectedFile ${expectedFile} not exists for ${clazz}") + } + expectedFile = expectedFile.canonicalFile.absoluteFile + List files = UrlCLassLoaderUtils2.getClassLocationAll2(clazz); + switch (files.size()) { + case 0: + addProblem(clazz.name, "class was not found : ${clazz.name}") + case 1: + File actualFile = files[0] + if (actualFile == null) { + throw new Exception("actual file is null for ${clazz} ${expectedFile}") + } + actualFile = actualFile.canonicalFile.absoluteFile + if (actualFile != expectedFile) { + addProblem(clazz.name, "actualFile != expectedFile : ${actualFile} != ${expectedFile}") + } + break; + default: + files = files.collect { it.canonicalFile } + addProblem(clazz.name, "found many path ${files.size()} : ${files.join(' , ')}") + } + } + + void checkClassLocation5(Class clazz, MavenIdContains mavenId) { + checkClassLocation5(clazz, mavenCommonUtils.findMavenOrGradle(mavenId.m)); + } + + void checkClassLocation5(Class clazz, File locationExpected) { + File currentLocation = UrlCLassLoaderUtils.getClassLocation(clazz); + if (locationExpected != currentLocation) { + addProblem(clazz.name, "class ${clazz.getName()} location != extected : ${currentLocation} != ${locationExpected}") +// throw new Exception("class " + clazz.getName() + " location strange " + currentLocation); + } + + } + + void addProblem(String className, String msg) { + ProblemInfoClass problemInfoClass = new ProblemInfoClass() + problemInfoClass.clazz = className + problemInfoClass.msg = msg + problemInfoClass.stackTrace = new JustStackTrace() + addProblemImpl(problemInfoClass) + } + + + void addProblemJustMsg(String msg) { + ProblemInfoClass problemInfoClass = new ProblemInfoClass() + problemInfoClass.msg = msg + problemInfoClass.stackTrace = new JustStackTrace() + addProblemImpl(problemInfoClass) + } + + + void addProblem2(String className, String msg, Throwable exception) { + ProblemInfoClass problemInfoClass = new ProblemInfoClass() + problemInfoClass.clazz = className + problemInfoClass.msg = msg + problemInfoClass.stackTrace = exception + addProblemImpl(problemInfoClass) + } + + void addProblemImpl(ProblemInfoClass problemInfoClass) { + problemCollector.addProblemImpl(problemInfoClass) + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClasspathTester.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClasspathTester.groovy index 2e9d78e0..96180578 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClasspathTester.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ClasspathTester.groovy @@ -1,15 +1,14 @@ package net.sf.jremoterun.utilities.nonjdk.classpath.tester +import groovy.transform.CompileStatic import net.sf.jremoterun.URLClassLoaderExt -import net.sf.jremoterun.utilities.ContextClassLoaderWrapper; +import net.sf.jremoterun.utilities.ContextClassLoaderWrapper import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.UrlCLassLoaderUtils import net.sf.jremoterun.utilities.classpath.AddFilesToUrlClassLoaderGroovy import net.sf.jremoterun.utilities.classpath.ClRef -import java.util.logging.Logger; -import groovy.transform.CompileStatic; - +import java.util.logging.Logger @CompileStatic class ClasspathTester { @@ -23,7 +22,7 @@ class ClasspathTester { filesAndMavenIds.each { adder.addGenericEntery(it) } ContextClassLoaderWrapper.wrap2(classLoader,{ if (checkNoGroovy) { - ClassPathTesterHelper.checkNoSuchClass(new ClRef(GroovyObject), classLoader) + ClassPathTesterHelper2.createClassPathTesterHelper2().checkNoSuchClass5(new ClRef(GroovyObject), classLoader) classLoader.addURL(UrlCLassLoaderUtils.getClassLocation(GroovyObject).toURL()) } else { diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/JavaToolsJarTester.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/JavaToolsJarTester.groovy new file mode 100644 index 00000000..560eefaf --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/JavaToolsJarTester.groovy @@ -0,0 +1,30 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.tester + + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import sun.jvmstat.monitor.HostIdentifier + +import java.util.logging.Logger + +@CompileStatic +class JavaToolsJarTester { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ClassPathTesterHelper2 helper + + JavaToolsJarTester(ClassPathTesterHelper2 helper) { + this.helper = helper + } + + void checkToolsJar() { +// Class hostId = + if(HostIdentifier.classLoader != JavaToolsJarTester.classLoader){ + helper.addProblem(HostIdentifier.name,"Class from stange classloader : ${HostIdentifier.classLoader}") + } + helper.checkClassOnce5(HostIdentifier, ClassPathTesterHelper2.mavenCommonUtils.getToolsJarFile()) + } + + +} \ No newline at end of file diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ProblemInfoClass.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ProblemInfoClass.groovy new file mode 100644 index 00000000..9a1966c6 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/ProblemInfoClass.groovy @@ -0,0 +1,15 @@ +package net.sf.jremoterun.utilities.nonjdk.classpath.tester + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemInfo; + +import java.util.logging.Logger; + +@CompileStatic +class ProblemInfoClass extends ProblemInfo{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + String clazz + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/StdClassPathTester.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/StdClassPathTester.groovy index f99dff3a..7b013ec1 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/StdClassPathTester.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/classpath/tester/StdClassPathTester.groovy @@ -10,35 +10,38 @@ import net.sf.jremoterun.utilities.nonjdk.classpath.CheckNonCache2 import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import net.sf.jremoterun.utilities.nonjdk.log.Log4j2Utils +import net.sf.jremoterun.utilities.nonjdk.problemchecker.ProblemCollectorIThrowImmediate import org.apache.log4j.Level import org.apache.logging.log4j.LogManager import org.slf4j.LoggerFactory -import sun.jvmstat.monitor.HostIdentifier import java.util.logging.Logger @CompileStatic -class StdClassPathTester extends ClassPathTesterHelper { +class StdClassPathTester implements Runnable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + ClassPathTesterHelper2 helper + + StdClassPathTester() { + this.helper = new ClassPathTesterHelper2(new ProblemCollectorIThrowImmediate()); + } @Override - public void runImpl() throws Exception { + public void run() { CheckNonCache2.check(); - checkClassOnce(Level, LatestMavenIds.log4jOld) - checkClassOnce(org.apache.commons.logging.LogFactory, CustObjMavenIds.commonsLoggingMavenId) - - checkClassOnce(org.slf4j.LoggerFactory, CustObjMavenIds.slf4jApi) - checkClassOnce(org.slf4j.Logger, CustObjMavenIds.slf4jApi) - + helper.checkClassOnce5(Level, LatestMavenIds.log4jOld) + helper.checkClassOnce5(org.apache.commons.logging.LogFactory, CustObjMavenIds.commonsLoggingMavenId) + helper.checkClassOnce5(org.slf4j.LoggerFactory, CustObjMavenIds.slf4jApi) + helper.checkClassOnce5(org.slf4j.Logger, CustObjMavenIds.slf4jApi) // checkClassOnce(com.jidesoft.swing.Gripper, new MavenId("com.jidesoft:jide-oss:3.6.18")) - checkClassOnce(Native, LatestMavenIds.jna) + helper.checkClassOnce5(Native, LatestMavenIds.jna) // checkClassOnce(org.jsoup.select.Elements, new MavenId('org.jsoup:jsoup:1.11.2')) // checkClassOnce(jcifs.Config, new MavenId("jcifs:jcifs:1.3.17")) // checkClassOnce(org.apache.http.auth.AuthScheme, new MavenId("org.apache.httpcomponents:httpclient:4.5.3")) @@ -47,24 +50,22 @@ class StdClassPathTester extends ClassPathTesterHelper { org.apache.log4j.Logger logger1 = org.apache.log4j.Logger.getLogger("test"); - checkClassInstanceOf(logger1, org.apache.log4j.Logger.class); + helper.checkClassInstanceOf5(logger1, org.apache.log4j.Logger.class); // System.setProperty(LogManager.FACTORY_PROPERTY_NAME, Log4jContextFactory.class.getName()); Log4j2Utils.checkAndFixFactory(); org.apache.logging.log4j.Logger logger2 = LogManager.getLogger("test"); - checkClassInstanceOf(logger2, org.apache.logging.log4j.core.Logger.class); + helper.checkClassInstanceOf5(logger2, org.apache.logging.log4j.core.Logger.class); org.slf4j.Logger loggerSl4j = LoggerFactory.getLogger("test"); // checkClassInstanceOf(loggerSl4j, org.apache.logging.slf4j.Log4jLogger.class); - checkFieldExists(Level, 'TRACE') + helper.checkFieldExists5(Level, 'TRACE') // getHostText used in jedit ssh // ClassPathTesterHelper.checkClassOnce(com.google.common.net.HostAndPort, LatestMavenIds.guavaMavenId) // com.google.common.net.HostAndPort.fromString('127.0.0.1:5223').getHostText(); - - URL jdkLoggerExtentionMethods = JrrClassUtils.currentClassLoader.getResource("META-INF/services/org.codehaus.groovy.runtime.ExtensionModule") - assert jdkLoggerExtentionMethods != null + helper.checkResourceExists("META-INF/services/org.codehaus.groovy.runtime.ExtensionModule") checkToolsJar() assert MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver == null @@ -74,9 +75,9 @@ class StdClassPathTester extends ClassPathTesterHelper { static void checkToolsJar() { -// Class hostId = - assert HostIdentifier.classLoader == StdClassPathTester.classLoader - checkClassOnce(HostIdentifier, ClassPathTesterHelper.mavenCommonUtils.getToolsJarFile()) + ClassPathTesterHelper2 helper2 = new ClassPathTesterHelper2(new ProblemCollectorIThrowImmediate()); + JavaToolsJarTester stdClassPathTester2 = new JavaToolsJarTester(helper2) + stdClassPathTester2.checkToolsJar() } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/classuggest/GetListOfClasses.groovy b/src/net/sf/jremoterun/utilities/nonjdk/classuggest/GetListOfClasses.groovy new file mode 100644 index 00000000..3afa1ba4 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/classuggest/GetListOfClasses.groovy @@ -0,0 +1,92 @@ +package net.sf.jremoterun.utilities.nonjdk.classuggest + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.groovystarter.ConsoleSymbols +import net.sf.jremoterun.utilities.nonjdk.classpath.UrlCLassLoaderUtils2 +import org.zeroturnaround.zip.ZipInfoCallback +import org.zeroturnaround.zip.ZipUtil + +import java.util.logging.Logger +import java.util.zip.ZipEntry + +@CompileStatic +class GetListOfClasses { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + + Object loadClassFromPackage2(Class sampleClass, String className) { + return loadClassFromPackage(sampleClass,className).newInstance() + } + + Class loadClassFromPackage(Class sampleClass, String className) { + if (className == ConsoleSymbols.question.s) { + List classes = getListOfClasses(sampleClass) + throw new IllegalArgumentException("List of classes : ${classes}") + } + String fullClassName = sampleClass.getPackage().getName()+'.' + className + try { + return sampleClass.getClassLoader().loadClass(fullClassName) + } catch (ClassNotFoundException e) { + List classes = getListOfClasses(sampleClass) + log.info "Failed load ${className}, available ${classes}" +// throw new ClassNotFoundException("Failed load ${className}, available ${classes}", e) + throw e + } + + } + + List getListOfClasses(Class sampleClass) { + File baseDir = UrlCLassLoaderUtils2.getClassLocationFirst(sampleClass) + String packName = sampleClass.getPackage().getName() + return getListOfClasses(baseDir, packName) + } + + List getListOfClasses(File baseDir, String packageName) { + packageName = packageName.replace('.', '/') + if (!packageName.endsWith('/')) { + packageName += '/' + } + if (baseDir.isDirectory()) { + File subDir = baseDir.child(packageName) + if (!subDir.exists()) { + throw new FileNotFoundException(subDir.getAbsolutePath()) + } + if (!subDir.isDirectory()) { + throw new IllegalArgumentException("not a dir : ${subDir}") + } + List names = subDir.listFiles().toList() + names = names.findAll { it.isFile() } + names = names.findAll { !it.getName().contains('$') } + names = names.findAll { it.getName().endsWith('.groovy') || it.getName().endsWith('.class') } + List res = names.collect { it.getName().replace('.groovy', '').replace('.class', '') } + res = res.findAll { it != null && it.length() > 0 } + if (res.size() == 0) { + throw new IllegalStateException("Not entries found for ${subDir}") + } + res = res.sort() + return res + } + if (!baseDir.getName().endsWith('.jar')) { + throw new IllegalArgumentException("should be jar file : ${baseDir}") + } + List res = [] + ZipInfoCallback zipInfoCallback = { + ZipEntry it -> + if (it.getName().startsWith(packageName)) { + res.add(it.getName().replace(packageName, '')) + } + } + ZipUtil.iterate(baseDir, zipInfoCallback) + res = res.findAll { !it.contains('/') } + res = res.collect { it.replace('.groovy', '').replace('.class', '') } + res = res.findAll { it != null && it.length() > 0 && !it.contains('$') } + if (res.size() == 0) { + throw new IllegalStateException("Not entries found for ${baseDir} ${packageName}") + } + res = res.sort() + return res; + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/AutoCompleteCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/AutoCompleteCompiler.groovy index a6ca8859..05c7c4de 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/AutoCompleteCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/AutoCompleteCompiler.groovy @@ -6,6 +6,9 @@ import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.classpath.CustomObjectHandler import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import net.sf.jremoterun.utilities.nonjdk.git.GitRef import net.sf.jremoterun.utilities.nonjdk.git.GitSpec @@ -24,8 +27,7 @@ class AutoCompleteCompiler { public static GitSpec gitSpec = new GitSpec('https://github.com/venkato/AutoComplete') EclipseJavaCompilerPure compilerPure = new EclipseJavaCompilerPure(); - GitRef gitRefSrc = new GitRef(gitSpec, 'src/main/java') - GitRef gitRefResources = new GitRef(gitSpec, 'src/main/resources') + FileChildLazyRef gitRefResources = GitSomeRefs.rstaAutoCompetionVenkato.childL( 'src/main/resources') CustomObjectHandler handler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler @@ -48,9 +50,9 @@ class AutoCompleteCompiler { void addDefaulSrc() { if (autoComplDir == null) { - autoComplDir = handler.resolveToFile(gitSpec) + autoComplDir = GitSomeRefs.rstaAutoCompetionVenkato.resolveToFile() } - compilerPure.addInDir handler.resolveToFile(gitRefSrc) + compilerPure.addInDir GitSomeRefs.rstaAutoCompetionVenkato.childL( 'src/main/java') compilerPure.outputDir = new File(autoComplDir, 'build') compilerPure.outputDir.mkdirs() } @@ -58,7 +60,7 @@ class AutoCompleteCompiler { File dist void zip() { - FileUtils.copyDirectory(handler.resolveToFile(gitRefResources), compilerPure.outputDir) + FileUtilsJrr.copyDirectory(handler.resolveToFile(gitRefResources), compilerPure.outputDir) dist = new File(autoComplDir, 'dist/AutoComplete.jar') dist.parentFile.mkdir() dist.delete() diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/CompileGroovyExtMethod2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/CompileGroovyExtMethod2.groovy index 836d8128..fb9c425c 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/CompileGroovyExtMethod2.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/CompileGroovyExtMethod2.groovy @@ -1,6 +1,7 @@ package net.sf.jremoterun.utilities.nonjdk.compile; import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.compiler3.CompileGroovyExtMethod import org.apache.commons.io.FileUtils import org.zeroturnaround.zip.ZipUtil; @@ -20,7 +21,7 @@ class CompileGroovyExtMethod2 extends CompileGroovyExtMethod{ File zipp() { File resource = createGroovyExtMethodDir(ifDir); - FileUtils.copyDirectory(resource, params.outputDir); + FileUtilsJrr.copyDirectory(resource, params.outputDir); File destJar = new File(ifDir, 'build/ifframework-ext-methods.jar') destJar.delete() assert !destJar.exists() diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/DockingFramesCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/DockingFramesCompiler.groovy index 8714edbc..f9b5dd52 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/DockingFramesCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/DockingFramesCompiler.groovy @@ -4,6 +4,7 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenCommonUtils import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs import java.util.logging.Logger @@ -24,7 +25,7 @@ class DockingFramesCompiler extends GenericCompiler { params.printWarning = false params.javaVersion = '1.8' if (baseDir2 == null) { - baseDir2 = GitReferences.dockingFrames.resolveToFile() + baseDir2 = GitSomeRefs.dockingFrames.resolveToFile() } log.info "${baseDir2}" List dirs = findSrc(baseDir2) diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/EclipsePluginsCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/EclipsePluginsCompiler.groovy index 2042949b..e28f677c 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/EclipsePluginsCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/EclipsePluginsCompiler.groovy @@ -7,6 +7,7 @@ import net.sf.jremoterun.utilities.groovystarter.st.JdkLogFormatter import net.sf.jremoterun.utilities.mdep.DropshipClasspath import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs import net.sf.jremoterun.utilities.nonjdk.classpath.CutomJarAdd +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds @@ -18,8 +19,8 @@ class EclipsePluginsCompiler extends GenericCompiler { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); List mavenIds = [ - LatestMavenIds.eclipseJavaCompiler, - LatestMavenIds.eclipseJavaAstParser, + CustObjMavenIds.eclipseJavaCompiler, + CustObjMavenIds.eclipseJavaAstParser, LatestMavenIds.jodaTime, // new MavenId('org.eclipse.platform:org.eclipse.equinox.common:3.9.0'), // new MavenId('org.eclipse.platform:org.eclipse.core.resources:3.12.0'), diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/GenericCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/GenericCompiler.groovy index 2dde8ec8..492f38ba 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/GenericCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/GenericCompiler.groovy @@ -5,6 +5,7 @@ import net.sf.jremoterun.utilities.classpath.MavenCommonUtils import net.sf.jremoterun.utilities.classpath.MavenIdContains import net.sf.jremoterun.utilities.classpath.ToFileRef2 import net.sf.jremoterun.utilities.classpath.ToFileRefSelf +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.compiler3.CompileRequestClient import net.sf.jremoterun.utilities.nonjdk.compiler3.GroovyCompilerParams import org.apache.commons.io.FileUtils; @@ -44,16 +45,16 @@ abstract class GenericCompiler { static void copyMavenIdToDir(MavenIdContains mavenId, File toDir){ File fileMavenId = new MavenCommonUtils().findMavenOrGradle(mavenId.m) assert fileMavenId!=null - FileUtils.copyFileToDirectory(fileMavenId, toDir) + FileUtilsJrr.copyFileToDirectory(fileMavenId, toDir) } void addInDir(File... files){ params.addInDir(files) } - void addInDir(ToFileRefSelf toFileRef){ - params.addInDir toFileRef.resolveToFile() - } +// void addInDir(ToFileRefSelf toFileRef){ +// params.addInDir toFileRef.resolveToFile() +// } void addInDir(ToFileRef2 toFileRef){ params.addInDir toFileRef.resolveToFile() diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/GroovyCustomCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/GroovyCustomCompiler.groovy index c7b5b724..cbd1587d 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/GroovyCustomCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/GroovyCustomCompiler.groovy @@ -2,7 +2,12 @@ package net.sf.jremoterun.utilities.nonjdk.compile import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs import net.sf.jremoterun.utilities.nonjdk.antutils.JrrAntUtils +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs2 import net.sf.jremoterun.utilities.nonjdk.langi.JrrStaticCompilationVisitor import net.sf.jremoterun.utilities.nonjdk.log.FileExtentionClass import net.sf.jremoterun.utilities.nonjdk.log.JdkLoggerExtentionClass @@ -26,17 +31,18 @@ class GroovyCustomCompiler extends GenericCompiler { } params.javaVersion = '1.6' params.addInDir new File(baseDir, "groovycustom/src") - params.addInDir new File(baseDir, "src-logger-ext-methods") + params.addInDir new File(baseDir, IfFrameworkSrcDirs.src_logger_ext_methods.dirName) params.outputDir = new File(baseDir, "build/groovycustom1") } File dest - void zip() { - FileUtils.copyDirectory(new File(baseDir, "resources-groovy"), params.outputDir) + File zip() { + FileUtilsJrr.copyDirectory(new File(baseDir, "resources-groovy"), params.outputDir) dest = new File(baseDir, "build/groovy_custom.jar") dest.delete() ZipUtil.pack(params.outputDir, dest) + return dest } @@ -48,6 +54,13 @@ class GroovyCustomCompiler extends GenericCompiler { } + void updateCompilerDefaultDir() { + File child = GitSomeRefs.starter.childL('libs/origin/groovy_custom.jar').resolveToFile() + assert child.exists() + updateCompiler(child) + FileUtilsJrr.copyFile(child, JrrStarterJarRefs2.groovy_custom.resolveToFile()) + } + void updateCompiler(File compilerJar) { List classes3 = (List) [JdkLoggerExtentionClass, FileExtentionClass, CompileStatic,] diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaInitPluginCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaInitPluginCompiler.groovy index ad4434f1..ca972527 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaInitPluginCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaInitPluginCompiler.groovy @@ -6,7 +6,11 @@ import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs import net.sf.jremoterun.utilities.nonjdk.git.GitRef import org.apache.commons.codec.digest.DigestUtils import org.apache.commons.io.FileUtils @@ -51,7 +55,7 @@ class IdeaInitPluginCompiler extends GenericCompiler { } log.info "file not found : ${child}" } - File f = new GitRef(GitReferences.starter, "onejar/jrrutilities.jar").resolveToFile() + File f = JrrStarterJarRefs.jrrutilitiesOneJar.resolveToFile() return f } @@ -62,9 +66,10 @@ class IdeaInitPluginCompiler extends GenericCompiler { params.outputDir = new File(client.ifDir, 'build/ideainitpluginbuild') params.outputDir.mkdirs() params.javaVersion = '1.6' - File dir = new File(client.ifDir, 'src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init') - assert dir.exists() - params.files.addAll(dir.listFiles().toList()) + params.addInDir IfFrameworkSrcDirs.src_idea.childL('net/sf/jremoterun/utilities/nonjdk/idea/init'); +// File dir = new File(client.ifDir, 'src-idea/net/sf/jremoterun/utilities/nonjdk/idea/init') +// assert dir.exists() +// params.files.addAll(dir.listFiles().toList()) client.adder.add getJrrUtilsJar() @@ -76,10 +81,10 @@ class IdeaInitPluginCompiler extends GenericCompiler { } void testUpdateIdeaJar(File tmpJar, File metaInf, File targetJar) { - assert targetJar.parentFile.exists() + assert targetJar.getParentFile().exists() testUpdateIdeaJar2(tmpJar, metaInf) - assert targetJar.parentFile.exists() - FileUtils.copyFile(tmpJar, targetJar) + assert targetJar.getParentFile().exists() + FileUtilsJrr.copyFile(tmpJar, targetJar) assert DigestUtils.sha256(tmpJar.bytes) == DigestUtils.sha256(targetJar.bytes) tmpJar.delete() log.info "file updated : ${targetJar}" @@ -91,7 +96,7 @@ class IdeaInitPluginCompiler extends GenericCompiler { assert !tmpJar.exists() assert metaInf.directory - FileUtils.copyDirectoryToDirectory(metaInf, params.outputDir) + FileUtilsJrr.copyDirectoryToDirectory(metaInf, params.outputDir) ZipUtil.pack(params.outputDir, tmpJar) diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaPluginCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaPluginCompiler.groovy index 04167e54..afd4f882 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaPluginCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaPluginCompiler.groovy @@ -40,9 +40,18 @@ class IdeaPluginCompiler extends IfFrameworkCompiler { } - static void addIdeaCp(AddFilesToClassLoaderCommon adder,File ideaDir2){ - adder.addAllJarsInDir new File(ideaDir2, "lib/") - adder.addAllJarsInDir new File(ideaDir2, 'plugins/Groovy/lib/'); + static void addIdeaCp(AddFilesToClassLoaderCommon adder,File ideaDir){ + assert ideaDir.exists() + adder.addAllJarsInDir new File(ideaDir, "plugins/git4idea/lib/") + adder.add new File(ideaDir, "plugins/github/lib/github.jar") + adder.add new File(ideaDir, "plugins/terminal/lib/terminal.jar") + adder.addAllJarsInDir new File(ideaDir, "lib/") + adder.addAllJarsInDir new File(ideaDir, 'plugins/Groovy/lib/'); + adder.addAllJarsInDirAndSubdirs(new File(ideaDir, 'plugins/Kotlin/lib')) + File javaPlauginDir = new File(ideaDir, 'plugins/java/lib/'); + if(javaPlauginDir.exists()){ + adder.addAllJarsInDir(javaPlauginDir) + } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaSourcesCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaSourcesCompiler.groovy index 26251d44..be727f0f 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaSourcesCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/IdeaSourcesCompiler.groovy @@ -8,6 +8,7 @@ import net.sf.jremoterun.utilities.mdep.DropshipClasspath import net.sf.jremoterun.utilities.nonjdk.IfFrameworkResourceDirs import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import java.util.logging.Logger @@ -26,9 +27,11 @@ class IdeaSourcesCompiler extends IfFrameworkCompiler { ] public static List mavenIds = [ - CustObjMavenIds.git, + GitMavenIds.jgit, LatestMavenIds.jsoup, LatestMavenIds.jodaTime, + LatestMavenIds.javaCompiler2Janino, + LatestMavenIds.javaCompilerJaninoCommon, ] diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/IfFrameworkCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/IfFrameworkCompiler.groovy index 058d2d00..3c2f23f5 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/IfFrameworkCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/IfFrameworkCompiler.groovy @@ -4,18 +4,32 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.ContextClassLoaderWrapper import net.sf.jremoterun.utilities.JavaVMClient import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderGroovy import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.groovystarter.GroovyRunnerConfigurator2 import net.sf.jremoterun.utilities.groovystarter.st.JdkLogFormatter import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import net.sf.jremoterun.utilities.nonjdk.IfFrameworkSrcDirs import net.sf.jremoterun.utilities.nonjdk.InfocationFrameworkStructure import net.sf.jremoterun.utilities.nonjdk.classpath.CutomJarAdd +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.AsmOw +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.BouncyCastleMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitlabLibsMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.MaryDependentMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.MavenMavenIdRandom +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.MavenMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.MavenResolverMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.NexusSearchMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.Okhttp3MavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.SshdMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs2.CutomJarAdd1 import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GroovyMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.Log4j2MavenIds +import org.zeroturnaround.zip.ZipUtil import java.util.logging.Logger @@ -32,10 +46,37 @@ class IfFrameworkCompiler extends GenericCompiler { LatestMavenIds.rstaui, LatestMavenIds.rstaAutoComplete, Log4j2MavenIds.slf4j_impl, - LatestMavenIds.sshd, + SshdMavenIds.core, + SshdMavenIds.netty, + SshdMavenIds.scp, + SshdMavenIds.common, + GitMavenIds.jgit_ssh_jsch, LatestMavenIds.jline2, LatestMavenIds.jline3, - LatestMavenIds.commonsIo, + CustObjMavenIds.commonsIo, + LatestMavenIds.quickfixj, + LatestMavenIds.minaCore, + BouncyCastleMavenIds.bctls_jdk15on, + BouncyCastleMavenIds.bcpkix_jdk15on, + GitlabLibsMavenIds.coreLib, + GitlabLibsMavenIds.jakartaWsRsApi, + // janino used in idea plugin only + LatestMavenIds.javaCompiler2Janino, + LatestMavenIds.javaCompilerJaninoCommon, + LatestMavenIds.plexusClassworlds, + LatestMavenIds.jodaTime, + LatestMavenIds.svnNativeClintWrapper, + LatestMavenIds.svnClientAdapterJavahlUseless, + LatestMavenIds.svnClientAdapterMainUseless, + LatestMavenIds.maven_resolver_provider, + LatestMavenIds.plexus_utils, + LatestMavenIds.commonsCli, + Okhttp3MavenIds.okhttp, + MavenMavenIdRandom.sharedUtils, + MavenMavenIdRandom.wagonProviderApi, +// MavenMavenIds.embedder, +// MavenMavenIds.compat, +// MavenMavenIds.model, // LatestMavenIds.jsoup, ] @@ -46,33 +87,61 @@ class IfFrameworkCompiler extends GenericCompiler { client.adder.add CutomJarAdd1.downloadIdw() } + static void addLibs(AddFilesToClassLoaderGroovy adder){ + adder.addFileWhereClassLocated JdkLogFormatter + adder.addFileWhereClassLocated JrrClassUtils + adder.addFileWhereClassLocated JavaVMClient + adder.addAll DropshipClasspath.allLibsWithGroovy + adder.addAll GroovyMavenIds.all + adder.addAll MavenResolverMavenIds.all + adder.addAll MavenMavenIds.all + adder.addAll mavenIds + adder.addAll GitlabLibsMavenIds.fastXmls + adder.addAll GitlabLibsMavenIds.glassfish + adder.addAll NexusSearchMavenIds.all + adder.addAll LatestMavenIds.usefulMavenIdSafeToUseLatest + adder.addAll AsmOw.all + adder.addAll MaryDependentMavenIds.values().toList() + // adder.add GroovyMavenIds.groovyCore + adder.add JeditTermCompilerConsoleCompiler.compileIfNeededS() + CutomJarAdd.addCustom(adder) + + } + void prepare() { if (baseDir == null) { baseDir = client.ifDir } + // if provider loaded java.nio.file.spi.FileSystemProvider, then + // org.apache.sshd.client.subsystem.sftp.SftpFileSystemProvider loaded, which cause load + // org.apache.sshd.common.io.IoServiceFactoryFactory + // Could be 2 Factories, which it doesn't like and throw Exception 2 Factory found + net.sf.jremoterun.utilities.nonjdk.shell.GroovySehllSshServiceSettings.setSshProps() params.printWarning = false params.javaVersion = '1.6' params.outputDir = baseDir.child('build/ifbuild') params.outputDir.mkdirs() params.addInDir GitReferences.jnaplatext.resolveToFile() - client.adder.addFileWhereClassLocated JdkLogFormatter - client.adder.addFileWhereClassLocated JrrClassUtils - client.adder.addFileWhereClassLocated JavaVMClient - client.adder.addAll DropshipClasspath.allLibsWithGroovy - client.adder.addAll GroovyMavenIds.all - client.adder.addAll mavenIds - client.adder.addAll NexusSearchMavenIds.all - client.adder.addAll LatestMavenIds.usefulMavenIdSafeToUseLatest - // client.adder.add GroovyMavenIds.groovyCore - client.adder.add JeditTermCompilerConsoleCompiler.compileIfNeededS() - CutomJarAdd.addCustom(client.adder) + addLibs(client.adder); +// client.adder.addFileWhereClassLocated JdkLogFormatter +// client.adder.addFileWhereClassLocated JrrClassUtils +// client.adder.addFileWhereClassLocated JavaVMClient +// client.adder.addAll DropshipClasspath.allLibsWithGroovy +// client.adder.addAll GroovyMavenIds.all +// client.adder.addAll mavenIds +// client.adder.addAll NexusSearchMavenIds.all +// client.adder.addAll LatestMavenIds.usefulMavenIdSafeToUseLatest +// client.adder.addAll AsmOw.all +// client.adder.addAll MaryDependentMavenIds.values().toList() +// client.adder.add JeditTermCompilerConsoleCompiler.compileIfNeededS() +// CutomJarAdd.addCustom(client.adder) List dirs = InfocationFrameworkStructure.dirs2 dirs.each { params.addInDir(baseDir.child(it)) } params.addInDir baseDir.child("groovycustom/src") - params.addInDir baseDir.child("src-logger-ext-methods") + params.addInDir baseDir.child(IfFrameworkSrcDirs.src_logger_ext_methods.dirName) addIdw() @@ -88,10 +157,18 @@ class IfFrameworkCompiler extends GenericCompiler { } void addToolsJar() { - client.adder.add mcu.getToolsJarFile() + File toolsJar = mcu.getToolsJarFile() + if(toolsJar.exists()) { + client.adder.add toolsJar + } } + + void zipp(File destJar) { + ZipUtil.pack(params.outputDir, destJar) + } + static ClRef ideaRedefinitionTester = new ClRef('net.sf.jremoterun.utilities.nonjdk.idea.IdeaRedefineClassloaderTester') static ClRef commonRedefinitionTester = new ClRef('net.sf.jremoterun.utilities.nonjdk.javassist.ClassRedefinitionTester') @@ -111,4 +188,6 @@ class IfFrameworkCompiler extends GenericCompiler { } + + } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/JeditTermClassChecker.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/JeditTermClassChecker.groovy new file mode 100644 index 00000000..00f807d2 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/JeditTermClassChecker.groovy @@ -0,0 +1,15 @@ +package net.sf.jremoterun.utilities.nonjdk.compile + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class JeditTermClassChecker implements Runnable{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void run() { + + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/JeditTermCompilerConsoleCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/JeditTermCompilerConsoleCompiler.groovy index 6a23cbd5..146b8172 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/JeditTermCompilerConsoleCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/JeditTermCompilerConsoleCompiler.groovy @@ -2,16 +2,20 @@ package net.sf.jremoterun.utilities.nonjdk.compile import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustomRefsUrls import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JeditermBinRefs2 import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import net.sf.jremoterun.utilities.nonjdk.javacompiler.EclipseJavaCompilerPure +import org.apache.commons.io.FileUtils import org.zeroturnaround.zip.ZipUtil import java.util.logging.Logger @CompileStatic -class JeditTermCompilerConsoleCompiler { +class JeditTermCompilerConsoleCompiler { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); @@ -25,6 +29,11 @@ class JeditTermCompilerConsoleCompiler { LatestMavenIds.jetbrainsAnnotations, ] + + ClRef clRef1 = new ClRef('com.jediterm.ssh.jsch.JSchTtyConnector'); + ClRef clRef2 = new ClRef('com.jediterm.terminal.ui.TerminalPanel'); + + EclipseJavaCompilerPure compilerPure = new EclipseJavaCompilerPure(); JeditTermCompilerConsoleCompiler() { @@ -42,46 +51,126 @@ class JeditTermCompilerConsoleCompiler { compilerPure.outputDir.mkdirs() compilerPure.adder.addAll mavenIds + compilerPure.adder.add CustomRefsUrls.pureJavacommnyJetBrainsUrl + + compilerPure.addInDir GitReferences.pty4jJetbrainsSrc + - compilerPure.addInDir GitReferences.pty4jSrc - compilerPure.addInDir GitReferences.purejavacommTraffSrc JeditermBinRefs2.all.each { compilerPure.addInDir(it) } compilerPure.javaVersion = '1.8' + hackSpeicicClass() + hackSpeicicClass2() log.info("out dir : ${compilerPure.outputDir}") } - void detectBuildDir(){ + + public static String createJSchMethodName = 'createJSch'; + + void hackSpeicicClass() { + String specificClassSuffix1 = clRef1.className.replace('.', '/') + '.java'; + File specificFile = JeditermBinRefs2.ssh.childL(specificClassSuffix1).resolveToFile() + assert specificFile.exists() + File fileToRemove = compilerPure.files.find { it.getName() == specificFile.getName() } + assert compilerPure.files.remove(fileToRemove) + String text = specificFile.text + String fromText1='JSch jsch = new JSch();' + String fromText2='private Session connectSession(Questioner questioner) throws JSchException {' + assert text.contains(fromText1) + assert text.contains(fromText2) + if (text.contains(fromText1)) { + text = text.replace(fromText1, "JSch jsch = ${createJSchMethodName}();") + text = text.replace(fromText2, """ + +protected JSch ${createJSchMethodName}(){return new JSch();} + +protected Session connectSession(Questioner questioner) throws JSchException { + +""") + } + File srcOverride = buildDir.child('src_override') + srcOverride.mkdir() + assert srcOverride.exists() + File fileOverride = srcOverride.child(specificFile.getName()) + fileOverride.text = text + compilerPure.files.add(fileOverride) + + } + + + void hackSpeicicClass2() { + String specificClassSuffix1 = clRef2.className.replace('.', '/') + '.java'; + File specificFile = JeditermBinRefs2.terminal.childL(specificClassSuffix1).resolveToFile(); + assert specificFile.exists() + File fileToRemove = compilerPure.files.find { it.getName() == specificFile.getName() } + assert compilerPure.files.remove(fileToRemove) + String text = specificFile.text + String fromText1='private void pasteFromClipboard(boolean useSystemSelectionClipboardIfAvailable) {' + String fromText2='private HyperlinkStyle findHyperlink(Point p) {' + assert text.contains(fromText1) + assert text.contains(fromText2) + if (text.contains(fromText1)) { + text = text.replace(fromText1, "protected void pasteFromClipboard(boolean useSystemSelectionClipboardIfAvailable) {") + text = text.replace(fromText2, "protected HyperlinkStyle findHyperlink(Point p) {") + } + File srcOverride = buildDir.child('src_override') + srcOverride.mkdir() + assert srcOverride.exists() + File fileOverride = srcOverride.child(specificFile.getName()) + fileOverride.text = text + compilerPure.files.add(fileOverride) + + } + + + void detectBuildDir() { if (buildDir == null) { File baseDir = JeditermBinRefs2.terminal.ref.specOnly.resolveToFile() buildDir = baseDir.child('build') } } - static File compileIfNeededS(){ + static File compileIfNeededS() { return new JeditTermCompilerConsoleCompiler().compileIfNeeded() } - File compileIfNeeded(){ + File compileIfNeeded() { detectBuildDir() - File zipFile = buildDir.child('jediterm.jar ..') - if(!zipFile.exists()){ - log.info "compiling JeditTerm" - prepare() - compilerPure.compile() - zipp() - log.info "JeditTerm compiled" + File zipFile = buildDir.child('jediterm.jar') + if (!zipFile.exists()) { + doCompile() } assert zipFile.exists() return zipFile } + void doCompile() { + log.info "compiling JeditTerm" + prepare() + compilerPure.compile() + zipp() + log.info "JeditTerm compiled" + } + + + void checkSpecificFile() { + String specificClassSuffix1 = clRef1.className.replace('.', '/') + '.class'; + File f = compilerPure.outputDir.child(specificClassSuffix1) + assert f.exists() + boolean methodExists = f.text.contains(createJSchMethodName) + assert methodExists + log.info "${createJSchMethodName} method found" + } + File zipp() { assert buildDir.exists() + checkSpecificFile() File zipFile = buildDir.child('jediterm.jar') - zipFile.delete() - assert !zipFile.exists() - ZipUtil.pack(compilerPure.outputDir, zipFile) + File zipFileTmp = buildDir.child('jeditermTmp.jar') + zipFileTmp.delete() + assert !zipFileTmp.exists() + ZipUtil.pack(compilerPure.outputDir, zipFileTmp) + FileUtilsJrr.copyFile(zipFileTmp, zipFile) return zipFile; } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/JhexCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/JhexCompiler.groovy index 2d569daa..b8081492 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/JhexCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/JhexCompiler.groovy @@ -5,17 +5,18 @@ import net.sf.jremoterun.utilities.JavaVMClient import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.groovystarter.st.JdkLogFormatter import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import net.sf.jremoterun.utilities.nonjdk.javacompiler.EclipseJavaCompilerPure import java.util.logging.Logger @CompileStatic -class JhexCompiler { +class JhexCompiler { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - List mavenIds =[ + List mavenIds = [ LatestMavenIds.guavaMavenId, ] @@ -24,17 +25,14 @@ class JhexCompiler { void prepare() { // params.printWarning = false - compilerPure.outputDir = GitReferences.jhexViewer.specOnly.resolveToFile().child('build/b1') + compilerPure.outputDir = GitSomeRefs.jhexViewer.childL('build/b1').resolveToFile() compilerPure.outputDir.mkdirs() // addInDir GitReferences.jhexViewer - File baseDir = GitReferences.jhexViewer.resolveToFile() - File subDir = baseDir.child('src/main/java/com/google/security/zynamics/zylib') - compilerPure. addInDir subDir.child('gui/JHexPanel/') -// addInDir subDir.child('general/') - compilerPure.addInDir subDir.child('gui/JCaret/') - compilerPure.addInDir subDir.child('general/Convert.java') - compilerPure.addInDir subDir.child('gui/GuiHelper.java') + compilerPure.addInDir GitSomeRefs.jhexViewer.childL('src/main/java/com/google/security/zynamics/zylib/gui/JHexPanel/') + compilerPure.addInDir GitSomeRefs.jhexViewer.childL('src/main/java/com/google/security/zynamics/zylib/gui/JCaret/') + compilerPure.addInDir GitSomeRefs.jhexViewer.childL('src/main/java/com/google/security/zynamics/zylib/general/Convert.java') + compilerPure.addInDir GitSomeRefs.jhexViewer.childL('src/main/java/com/google/security/zynamics/zylib/gui/GuiHelper.java') compilerPure.adder.addAll mavenIds compilerPure.adder.addFileWhereClassLocated(JavaVMClient) @@ -43,5 +41,4 @@ class JhexCompiler { } - } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/JnaCoreCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/JnaCoreCompiler.groovy index a1c4a6b4..fec8ba04 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/JnaCoreCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/JnaCoreCompiler.groovy @@ -4,6 +4,7 @@ import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs import net.sf.jremoterun.utilities.nonjdk.javacompiler.EclipseJavaCompilerPure import org.junit.Test import org.zeroturnaround.zip.ZipUtil @@ -22,7 +23,7 @@ class JnaCoreCompiler { void prepare() { if (baseDir == null) { - baseDir = GitReferences.jnaRepo.resolveToFile() + baseDir = GitSomeRefs.jnaRepo.resolveToFile() } compilerPure.adder.addFileWhereClassLocated(JrrUtilities) diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/JnaJvmtiCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/JnaJvmtiCompiler.groovy index 702aaebc..4f388d74 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/JnaJvmtiCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/JnaJvmtiCompiler.groovy @@ -5,7 +5,9 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.classpath.MavenIdContains import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import org.junit.Test import org.zeroturnaround.zip.ZipUtil @@ -25,13 +27,13 @@ class JnaJvmtiCompiler extends GenericCompiler { CustObjMavenIds.commonsLoggingMavenId, LatestMavenIds.commonsCollection, LatestMavenIds.log4jOld, - LatestMavenIds.commonsIo, - LatestMavenIds.git, + CustObjMavenIds.commonsIo, + GitMavenIds.jgit, ] void prepare() { if (baseDir == null) { - baseDir = GitReferences.jnaRepo.resolveToFile() + baseDir = GitSomeRefs.jnaRepo.resolveToFile() } client.adder.addAll mavenIds client.adder.add GitReferences.jnaCore diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrCoreCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrCoreCompiler.groovy index efb586f7..3e726e18 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrCoreCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrCoreCompiler.groovy @@ -2,17 +2,21 @@ package net.sf.jremoterun.utilities.nonjdk.compile import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds +import net.sf.jremoterun.utilities.nonjdk.javacompiler.EclipseJavaCompilerPure import org.apache.commons.io.FileUtils import org.zeroturnaround.zip.ZipUtil import java.util.logging.Logger @CompileStatic -class JrrCoreCompiler extends GenericCompiler { +class JrrCoreCompiler { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + EclipseJavaCompilerPure compilerPure = new EclipseJavaCompilerPure(); + public static List mavenIds = [ LatestMavenIds.swtWin, LatestMavenIds.eclipseWorkbench, @@ -21,20 +25,23 @@ class JrrCoreCompiler extends GenericCompiler { File baseDir void prepare() { - params.javaVersion = '1.5' - client.adder.addAll mavenIds - params.addInDir new File(baseDir, 'src') - params.outputDir = new File(baseDir, 'build/classes') - params.outputDir.mkdirs() + compilerPure.javaVersion = '1.5' + compilerPure.adder.addAll mavenIds + compilerPure.addInDir new File(baseDir, 'src') + compilerPure.outputDir = new File(baseDir, 'build/classes2') + compilerPure.outputDir.mkdirs() } File zipp() { - FileUtils.copyDirectoryToDirectory(new File(baseDir,"src/META-INF"),params.outputDir); - File destJar = new File(baseDir, 'build/jremoterun.jar'); + FileUtilsJrr.copyDirectoryToDirectory(new File(baseDir,"src/META-INF"),compilerPure.outputDir); + File destJar = new File(baseDir, 'build/jremoterun_try.jar'); + assert destJar.parentFile.exists() - ZipUtil.pack(params.outputDir, destJar) - return destJar + ZipUtil.pack(compilerPure.outputDir, destJar) + File dest2Jar = new File(baseDir, 'build/jremoterun.jar'); + FileUtilsJrr.copyFile(destJar,dest2Jar) + return dest2Jar } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrJavassistUtilsCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrJavassistUtilsCompiler.groovy index d0ebbd7e..ed32096d 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrJavassistUtilsCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrJavassistUtilsCompiler.groovy @@ -2,8 +2,15 @@ package net.sf.jremoterun.utilities.nonjdk.compile import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.classpath.MavenCommonUtils +import net.sf.jremoterun.utilities.classpath.MavenFileType2 import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds +import org.apache.commons.io.FileUtils +import org.zeroturnaround.zip.NameMapper +import org.zeroturnaround.zip.ZipUtil import java.util.logging.Logger @@ -11,6 +18,7 @@ import java.util.logging.Logger class JrrJavassistUtilsCompiler extends GenericCompiler { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public ClRef defaultRepositoryCacheManagerClRef = new ClRef('org.apache.ivy.core.cache.DefaultRepositoryCacheManager') public static List mavenIds = [ @@ -18,13 +26,46 @@ class JrrJavassistUtilsCompiler extends GenericCompiler { ] void prepare() { - params.javaVersion = '1.6' + params.javaVersion = '1.7' client.adder.addAll DropshipClasspath.allLibsWithGroovy client.adder.addAll mavenIds client.adder.add mcu.getToolsJarFile() // client.adder.addMavenPath DropshipClasspath.sisiFileBin } + void updateDefaultRepositoryCacheManager(File srcDir ){ + String suffix = defaultRepositoryCacheManagerClRef.className.replace('.','/')+'.java' + File childF = srcDir.child(suffix) + childF.delete() + assert !childF.exists() + childF.parentFile.mkdirs() + assert childF.parentFile.exists() + MavenCommonUtils mcu = new MavenCommonUtils(); + mcu.fileType = MavenFileType2.source.fileSuffix + File f =mcu.findMavenOrGradle(DropshipClasspath.ivyMavenId.m) + log.info "makeing class ${defaultRepositoryCacheManagerClRef} public from ${f}" + assert f!=null : DropshipClasspath.ivyMavenId.toString() + NameMapper nameMapper = new NameMapper() { + @Override + String map(String name) { + if(name==suffix){ + return name + } + return null + } + } + ZipUtil.unpack(f,srcDir,nameMapper) + assert childF.exists() + childF.text = childF.text.replace('private','public') + addInDir(srcDir) + } + + void zip(File destJar ){ + File tmpJar = params.outputDir.parentFile.child('jrrassist.jar') + ZipUtil.pack(params.outputDir, tmpJar) + FileUtilsJrr.copyFile(tmpJar,destJar) + log.info "copied to ${destJar}" + } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrUtilsCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrUtilsCompiler.groovy index 079e93c5..7ddab6a3 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrUtilsCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/JrrUtilsCompiler.groovy @@ -5,7 +5,9 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams import net.sf.jremoterun.utilities.mdep.DropshipClasspath +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import org.apache.commons.io.FileUtils import org.zeroturnaround.zip.ZipUtil @@ -25,7 +27,8 @@ class JrrUtilsCompiler extends GenericCompiler { void prepare() { params.javaVersion = '1.6' - client.adderParent.addAll DropshipClasspath.allLibsWithGroovy + client.adder.addAll DropshipClasspath.allLibsWithGroovy +// client.adderParent.addAll DropshipClasspath.allLibsWithGroovy client.adder.addGenericEnteries(mavenIds) client.adder.addFileWhereClassLocated(JrrUtilities) client.adder.addFileWhereClassLocated(JrrClassUtils) @@ -45,7 +48,7 @@ class JrrUtilsCompiler extends GenericCompiler { if(testFile.exists()) { baseDir = GroovyMethodRunnerParams.gmrp.grHome }else { - baseDir = GitReferences.starter.resolveToFile() + baseDir = GitSomeRefs.starter.resolveToFile() } } addInDir new File(baseDir, 'JrrUtilities/src') @@ -63,7 +66,8 @@ class JrrUtilsCompiler extends GenericCompiler { if(!destJar.parentFile.exists()){ assert destJar.parentFile.mkdir() } - FileUtils.copyFile(tmpJar,destJar) + FileUtilsJrr.copyFile(tmpJar,destJar) + log.info "copied to ${destJar}" return destJar } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/RDesktopCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/RDesktopCompiler.groovy index 3d9912d1..f774319f 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/RDesktopCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/RDesktopCompiler.groovy @@ -4,6 +4,7 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.BinaryWithSource import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import org.junit.Test @@ -45,7 +46,7 @@ class RDesktopCompiler extends GenericCompiler { } BinaryWithSource compileAndBuild(){ - baseDir = RstaCoreCompiler.handler.cloneGitRepo3.cloneGitRepo3(GitReferences.rdesktop) + baseDir = RstaCoreCompiler.handler.cloneGitRepo3.cloneGitRepo3(GitSomeRefs.rdesktop.getGitSpec()) prepare() compile() BinaryWithSource binaryWithSource = new BinaryWithSource(params.outputDir,new File(baseDir,'src')) diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/RstaCoreCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/RstaCoreCompiler.groovy index 7e5975da..78a4eff1 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/RstaCoreCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/RstaCoreCompiler.groovy @@ -9,6 +9,7 @@ import net.sf.jremoterun.utilities.groovystarter.st.SetConsoleOut2 import net.sf.jremoterun.utilities.mdep.DropshipClasspath import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.CustomObjectHandlerImpl +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GroovyMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds @@ -29,14 +30,14 @@ class RstaCoreCompiler extends GenericCompiler { LatestMavenIds.rsyntaxtextarea, LatestMavenIds.log4jOld, LatestMavenIds.rstaui, - CustObjMavenIds.git, + GitMavenIds.jgit, LatestMavenIds.jsoup, LatestMavenIds.junit, CustObjMavenIds.commnonsLang, LatestMavenIds.rsyntaxtextarea, LatestMavenIds.jodaTime, LatestMavenIds.commonsCodec, - LatestMavenIds.commonsIo, + CustObjMavenIds.commonsIo, DropshipClasspath.ivyMavenId, ] diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/RstaMainCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/RstaMainCompiler.groovy index bcc3ff8d..38cb990c 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/RstaMainCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/RstaMainCompiler.groovy @@ -5,6 +5,7 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.classpath.CustomObjectHandler import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds import net.sf.jremoterun.utilities.nonjdk.git.GitSpec @@ -57,7 +58,7 @@ class RstaMainCompiler { File dist; File zip() { - FileUtils.copyDirectory(new File(repoBase,'src/main/resources'),compilerPure.outputDir) + FileUtilsJrr.copyDirectory(new File(repoBase,'src/main/resources'),compilerPure.outputDir) dist = new File(repoBase,'build/rsta.jar'); dist.parentFile.mkdir() assert dist.parentFile.exists() diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/SshConsoleCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/SshConsoleCompiler.groovy index a4ef322c..42ad3ce1 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/SshConsoleCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/SshConsoleCompiler.groovy @@ -7,7 +7,9 @@ import net.sf.jremoterun.utilities.groovystarter.st.JdkLogFormatter import net.sf.jremoterun.utilities.mdep.DropshipClasspath import net.sf.jremoterun.utilities.nonjdk.InfocationFrameworkStructure import net.sf.jremoterun.utilities.nonjdk.classpath.CutomJarAdd +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.CustObjMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs.NexusSearchMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.SshdMavenIds import net.sf.jremoterun.utilities.nonjdk.classpath.refs2.CutomJarAdd1 import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GroovyMavenIds @@ -27,7 +29,7 @@ class SshConsoleCompiler extends GenericCompiler { LatestMavenIds.logbackCore, LatestMavenIds.guavaMavenId, LatestMavenIds.junit, - LatestMavenIds.sshd, + SshdMavenIds.core, LatestMavenIds.rsyntaxtextarea, LatestMavenIds.rstaui, LatestMavenIds.rstaAutoComplete, @@ -36,7 +38,7 @@ class SshConsoleCompiler extends GenericCompiler { Log4j2MavenIds.slf4j_impl, LatestMavenIds.jline2, LatestMavenIds.jline3, - LatestMavenIds.commonsIo, + CustObjMavenIds.commonsIo, ] SshConsoleCompiler() { @@ -62,6 +64,7 @@ class SshConsoleCompiler extends GenericCompiler { client.adder.addFileWhereClassLocated(JdkLogFormatter) client.adder.add mcu.getToolsJarFile() client.adder.addAll mavenIds + client.adder.addAll IfFrameworkCompiler.mavenIds client.adder.addAll GroovyMavenIds.all client.adder.addAll DropshipClasspath.allLibsWithGroovy client.adder.addAll NexusSearchMavenIds.all diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/TrolCommanderCompiler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/TrolCommanderCompiler.groovy index d75f8143..e39314f7 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/TrolCommanderCompiler.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/TrolCommanderCompiler.groovy @@ -5,6 +5,7 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.AddFilesToUrlClassLoaderGroovy import net.sf.jremoterun.utilities.classpath.CustomObjectHandler import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.classpath.refs.Log4j2MavenIds import org.apache.commons.io.FileUtils import org.junit.Test @@ -55,7 +56,7 @@ class TrolCommanderCompiler extends GenericCompiler { File zipp() { File classes2 = TrolCommanderCompilerAux.trolBinAndSrc2.resolveToFile() classes2.mkdir() - FileUtils.copyDirectory(params.outputDir, classes2) + FileUtilsJrr.copyDirectory(params.outputDir, classes2) File zipFile = new File(baseDir, TrolCommanderCompilerAux.trolBinAndSrc.pathInRepo) zipFile.delete() assert !zipFile.exists() diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/TrolCommanderCompilerAux.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/TrolCommanderCompilerAux.groovy index a3c0badc..d027469b 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/compile/TrolCommanderCompilerAux.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/TrolCommanderCompilerAux.groovy @@ -56,7 +56,7 @@ class TrolCommanderCompilerAux { , LatestMavenIds.commonsCollection , LatestMavenIds.commonsCollection4 , LatestMavenIds.commonsConfig - , LatestMavenIds.commonsIo + , CustObjMavenIds.commonsIo , CustObjMavenIds.commnonsLang , CustObjMavenIds.commonsLoggingMavenId , LatestMavenIds.httpClient diff --git a/src/net/sf/jremoterun/utilities/nonjdk/compile/auxh/AddGroovyToParentClResolver.groovy b/src/net/sf/jremoterun/utilities/nonjdk/compile/auxh/AddGroovyToParentClResolver.groovy new file mode 100644 index 00000000..7ca53850 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/compile/auxh/AddGroovyToParentClResolver.groovy @@ -0,0 +1,28 @@ +package net.sf.jremoterun.utilities.nonjdk.compile.auxh + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToClassLoaderCommon +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.JrrStarterJarRefs2 +import net.sf.jremoterun.utilities.nonjdk.compiler3.AddGroovyToParentCl; + +import java.util.logging.Logger; + +@CompileStatic +class AddGroovyToParentClResolver extends AddGroovyToParentCl{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void addGroovyJarToParentClassLoader(AddFilesToClassLoaderCommon adderParent) { + //File dir = GitReferences.groovyClasspathDir.resolveToFile() + adderParent.add JrrStarterJarRefs2.groovy_custom + adderParent.add JrrStarterJarRefs2.groovy + log.info "tmp cp1" + } + + static void setRef(){ + AddGroovyToParentCl.defaultAddtoParentCl = new AddGroovyToParentClResolver() + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/ConsoleProgramEnum.groovy b/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/ConsoleProgramEnum.groovy new file mode 100644 index 00000000..d46a489a --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/ConsoleProgramEnum.groovy @@ -0,0 +1,38 @@ +package net.sf.jremoterun.utilities.nonjdk.consoleprograms + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.ClRef + +@CompileStatic +enum ConsoleProgramEnum { + + sh(new ClRef('net.sf.jremoterun.utilities.nonjdk.shell.console.GroovyShellRunnerFromConsole')), +// sh ( new ClRef('net.sf.jremoterun.utilities.nonjdk.shell.GroovyShellRunner'), + k(new ClRef('net.sf.jremoterun.utilities.nonjdk.consoleprograms.ProgrammWinKill')), + p(new ClRef(ProxyConsolePrograms)), + gen(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.JrrConfigGenerator')), + addF(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.auxp.AddFilesToClassLoader')), + cm(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.auxp.ConsoleCompiler')), + jad(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.JrrConsoleDecompiler')), + jar(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.JrrJarRunner')), + asm(new ClRef('net.sf.jremoterun.utilities.nonjdk.asmow2.AsmConsoleDecompiler')), + svn(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.JrrSvnConsole')), + j2g(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.Java2GroovyConverter')), + gc2(new ClRef('net.sf.jremoterun.utilities.nonjdk.consoleprograms.GitCheckoutConsole')), + gradleWrapper(new ClRef('net.sf.jremoterun.utilities.nonjdk.consoleprograms.GradleWrapperRunner')), + + + + classAnalyze(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.ClassAnalyze')), + idea(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.JrrIdeaGenerator')), + downloadMavenId(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.DropshipDown3')), + dependencyChecker(new ClRef('net.sf.jremoterun.utilities.nonjdk.depanalise.DependencyChecker')), + classpathStatus(new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.ClasspathStatus')), + ; + + public ClRef clRef; + + ConsoleProgramEnum(ClRef clRef) { + this.clRef = clRef + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/ConsolePrograms.groovy b/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/ConsolePrograms.groovy index a84785cc..780c16c7 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/ConsolePrograms.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/ConsolePrograms.groovy @@ -69,13 +69,6 @@ class ConsolePrograms extends GroovyRunnerConfigurator2 { } - void addProgram(String acronym, ClRef impl) { - ClRef put = classMap.put(acronym, impl) - if (put != null) { - throw new Exception("shotcust ${acronym} already exist, old = ${put} , new = ${impl}") - } - } - void addProgram2(String acronym, Object impl) { if(impl instanceof Class){ addProgram(acronym,impl) @@ -85,7 +78,15 @@ class ConsolePrograms extends GroovyRunnerConfigurator2 { }else { throw new IllegalStateException("uknown object ${impl} for ${acronym}") } + } + + + void addProgram(String acronym, ClRef impl) { + ClRef put = classMap.put(acronym, impl) + if (put != null) { + throw new Exception("shotcust ${acronym} already exist, old = ${put} , new = ${impl}") + } } void addProgram(String acronym, Class impl) { diff --git a/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/DefaultConsolePrograms.groovy b/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/DefaultConsolePrograms.groovy index 7853a28c..d988f1f3 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/DefaultConsolePrograms.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/DefaultConsolePrograms.groovy @@ -2,8 +2,7 @@ package net.sf.jremoterun.utilities.nonjdk.consoleprograms import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.classpath.ClRef -import net.sf.jremoterun.utilities.nonjdk.depanalise.DependencyChecker +import net.sf.jremoterun.utilities.nonjdk.shell.console.GroovyShellRunnerFromConsoleWithMap import java.util.logging.Logger @@ -11,30 +10,12 @@ import java.util.logging.Logger class DefaultConsolePrograms extends ConsolePrograms { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static String shortcutsShName = 'sh2' - public static Map defaultShortcuts2 = [ - 'sh' : new ClRef('net.sf.jremoterun.utilities.nonjdk.shell.console.GroovyShellRunnerFromConsole'), -// 'sh' : new ClRef('net.sf.jremoterun.utilities.nonjdk.shell.GroovyShellRunner'), - 'k' : new ClRef('net.sf.jremoterun.utilities.nonjdk.consoleprograms.ProgrammWinKill'), - 'p' : ProxyConsolePrograms, - 'gen' : new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.JrrConfigGenerator'), - 'addF' : new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.auxp.AddFilesToClassLoader'), - 'cm' : new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.auxp.ConsoleCompiler'), - 'jad' : new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.JrrConsoleDecompiler'), - 'j2g' : new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.Java2GroovyConverter'), - 'gc2' : new ClRef('net.sf.jremoterun.utilities.nonjdk.consoleprograms.GitCheckoutConsole'), - - - - 'classAnalyze' : new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.ClassAnalyze'), - 'idea' : new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.JrrIdeaGenerator'), - 'downloadMavenId' : new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.DropshipDown3'), - 'dependencyChecker': DependencyChecker, - 'classpathStatus' : new ClRef('net.sf.jremoterun.utilities.nonjdk.classpath.console.ClasspathStatus'), - ] - -// public static Map defaultShortcuts = new HashMap<>(map23) - + public static Map defaultShortcuts2 = [: ] + static { + ConsoleProgramEnum.values().toList().each {defaultShortcuts2.put(it.name(),it.clRef)} + } DefaultConsolePrograms() { defaultShortcuts2.each { addProgram2(it.key, it.value) } @@ -47,6 +28,8 @@ class DefaultConsolePrograms extends ConsolePrograms { throw new IllegalArgumentException("Duplicate key : ${it.key} , before : ${before} , new : ${it.value}") } } + GroovyShellRunnerFromConsoleWithMap groovyShellRunnerFromConsoleWithMap = new GroovyShellRunnerFromConsoleWithMap(progi) + progi.put(shortcutsShName,groovyShellRunnerFromConsoleWithMap) } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/GitCheckoutConsole.groovy b/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/GitCheckoutConsole.groovy index 37669f5c..3e2caa34 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/GitCheckoutConsole.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/GitCheckoutConsole.groovy @@ -5,17 +5,19 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings import net.sf.jremoterun.utilities.groovystarter.ClassNameSynonym import net.sf.jremoterun.utilities.nonjdk.ConsoleRedirect +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.classpath.CustomObjectHandlerImpl import net.sf.jremoterun.utilities.nonjdk.classpath.console.JrrIdeaGenerator import net.sf.jremoterun.utilities.nonjdk.git.CloneGitRepo4 import net.sf.jremoterun.utilities.nonjdk.git.GitRef +import net.sf.jremoterun.utilities.nonjdk.git.GitRepoUtils import net.sf.jremoterun.utilities.nonjdk.git.GitSpec import org.apache.commons.io.FileUtils import java.util.logging.Logger @CompileStatic -class GitCheckoutConsole implements ClassNameSynonym{ +class GitCheckoutConsole implements ClassNameSynonym { File logfile @@ -54,17 +56,28 @@ class GitCheckoutConsole implements ClassNameSynonym{ } File clone(String repo) { + return clone3(repo, null, false) + } + + + File clone3(String repo, String branch, boolean forcePull) { doinit() if (repo.endsWith(".git")) { repo = repo.substring(0, repo.length() - 4) // repo = "${repo}.git" } - String dirSuffix = CloneGitRepo4.createGitRepoSuffix(repo) + '/git' + String dirSuffix = CloneGitRepo4.createGitRepoSuffix(repo) + '/'+ GitSpec.checkoutDirDefault File toDir3 = new File(cloneGitRepo3.gitBaseDir, dirSuffix) GitSpec gitSpec = new GitSpec() gitSpec.repo = repo - cloneGitRepo3.cloneGitRepo4(gitSpec, toDir3) - log.info "clone done : ${toDir3}" + gitSpec.branch = branch + if (forcePull && toDir3.exists()) { + GitRepoUtils gitRepoUtils = new GitRepoUtils(toDir3) + gitRepoUtils.pull() + } else { + cloneGitRepo3.cloneGitRepo4(gitSpec, toDir3) + log.info "clone done : ${toDir3}" + } return toDir3 } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/GradleWrapperRunner.groovy b/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/GradleWrapperRunner.groovy new file mode 100644 index 00000000..0b503980 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/consoleprograms/GradleWrapperRunner.groovy @@ -0,0 +1,43 @@ +package net.sf.jremoterun.utilities.nonjdk.consoleprograms + +import com.michaelalynmiller.jnaplatext.win32.ProcessUtils +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToUrlClassLoaderGroovy +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.groovystarter.ClassNameSynonym +import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams +import net.sf.jremoterun.utilities.groovystarter.st.GroovyMethodRunnerParams2 +import net.sf.jremoterun.utilities.groovystarter.st.PrintSelfHelp +import net.sf.jremoterun.utilities.nonjdk.PidDetector +import net.sf.jremoterun.utilities.nonjdk.WinProcessesFinder +import net.sf.jremoterun.utilities.nonjdk.winutils.WinCmdUtils2 +import org.jvnet.winp.WinProcess + +import java.util.logging.Logger + +@CompileStatic +class GradleWrapperRunner implements Runnable{ + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ClRef gradleWrapperCl = new ClRef('org.gradle.wrapper.GradleWrapperMain') + + @Override + void run() { + doJob() + } + + void doJob(){ + AddFilesToUrlClassLoaderGroovy adder = GroovyMethodRunnerParams.gmrp.addFilesToClassLoader + File wrapperJar = new File('gradle/wrapper/gradle-wrapper.jar'); + //wrapperJar = wrapperJar.canonicalFile.absoluteFile + //assert wrapperJar.exists() + adder.add(wrapperJar) + System.setProperty('org.gradle.appname','gradlew'); + GroovyMethodRunnerParams2.gmrp2.mainClass = gradleWrapperCl +// GroovyMethodRunnerParams2.gmrp2.runMainJavaMethod = true + + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyBC2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyBC2.groovy new file mode 100644 index 00000000..2aa94511 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyBC2.groovy @@ -0,0 +1,67 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import org.apache.commons.codec.binary.Base64 +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo +import org.bouncycastle.cert.X509CertificateHolder +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter +import org.bouncycastle.openssl.PEMKeyPair +import org.bouncycastle.openssl.PEMParser +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter +import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo + +import java.security.* +import java.security.spec.PKCS8EncodedKeySpec +import java.security.spec.X509EncodedKeySpec +import java.util.logging.Logger + +@CompileStatic +class AsymetricKeyBC2 { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + + + static Object loadKeyBc(byte[] bytes) { + PEMParser pemParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bytes))); + return pemParser.readObject(); + } + static Object loadKeyBcUseful(byte[] bytes) { + PEMParser pemParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bytes))); + Object object = pemParser.readObject(); + JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); + if (object instanceof PEMKeyPair) { + PEMKeyPair pemKeyPair = (PEMKeyPair) object; + KeyPair keyPair = converter.getKeyPair(pemKeyPair); + return keyPair + } + if (object instanceof SubjectPublicKeyInfo) { + SubjectPublicKeyInfo subjectPublicKeyInfo= (SubjectPublicKeyInfo) object; + PublicKey publicKey = converter.getPublicKey(subjectPublicKeyInfo) + return publicKey + } + if (object instanceof PrivateKeyInfo) { + PrivateKeyInfo subjectPublicKeyInfo= (PrivateKeyInfo) object; + return converter.getPrivateKey(subjectPublicKeyInfo) + } + if (object instanceof X509CertificateHolder) { + X509CertificateHolder certificateHolder = (X509CertificateHolder) object; + return new JcaX509CertificateConverter().setProvider( JavaSecurityProviders.BC.name() ) + .getCertificate( certificateHolder ); + } + return object; + } + + static KeyPair loadKeyPair(byte[] bytes) { + PEMParser pemParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bytes))); + PEMKeyPair pemKeyPair = (PEMKeyPair)pemParser.readObject(); + JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); + KeyPair keyPair = converter.getKeyPair(pemKeyPair); + return keyPair; + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyChecker2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyChecker2.groovy new file mode 100644 index 00000000..7b214960 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyChecker2.groovy @@ -0,0 +1,120 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import org.apache.commons.codec.binary.Base64 + +import java.security.* +import java.security.interfaces.DSAParams +import java.security.interfaces.DSAPrivateKey +import java.security.interfaces.DSAPublicKey +import java.security.interfaces.ECKey +import java.security.interfaces.ECPrivateKey +import java.security.interfaces.ECPublicKey +import java.security.interfaces.RSAPrivateCrtKey +import java.security.interfaces.RSAPrivateKey +import java.security.interfaces.RSAPublicKey +import java.security.spec.PKCS8EncodedKeySpec +import java.security.spec.X509EncodedKeySpec +import java.util.logging.Logger + +@CompileStatic +class AsymetricKeyChecker2 { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static void checkGeneric(File privateKeyF, File publicKeyF, KeyType keyType) { + PrivateKey privateKey = AsymetricKeyLoaderAny.loadKeyAny(privateKeyF, keyType, true) as PrivateKey + assert privateKey != null + PublicKey publicKey = AsymetricKeyLoaderAny.loadKeyAny(publicKeyF, keyType, false) as PublicKey + assert publicKey != null + checkGeneric(privateKey, publicKey) + } + + static void checkGeneric(PrivateKey privateKey, PublicKey publicKey) { + assert privateKey != null + assert publicKey != null + boolean checked = false; + if (privateKey instanceof RSAPrivateKey) { + RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey; + checkRsaKeyMatch1(rsaPrivateKey, publicKey as RSAPublicKey) + checkRsaKeyMatch3(rsaPrivateKey, publicKey as RSAPublicKey) + checked = true; + } + if (privateKey instanceof RSAPrivateCrtKey) { + RSAPrivateCrtKey rsaPrivateCrtKey = (RSAPrivateCrtKey) privateKey; + checkRsaKeyMatch2(rsaPrivateCrtKey, publicKey as RSAPublicKey) + checked = true; + } + if (privateKey instanceof DSAPrivateKey) { + DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) privateKey; + checkDsaKeyMatch(dsaPrivateKey, publicKey as DSAPublicKey) + checkDsaKeyMatch2(dsaPrivateKey, publicKey as DSAPublicKey) + checked = true; + } + if (privateKey instanceof ECKey) { + ECKey ecKey = (ECKey) privateKey; + checkKeyMatch4(ecKey, publicKey as ECKey) + checked = true; + } + if (privateKey instanceof ECPrivateKey) { + ECPrivateKey eCPrivateKey = (ECPrivateKey) privateKey; + EcPrivateKeyChecker.check1(eCPrivateKey, publicKey as ECPublicKey) + checked = true; + } + + assert checked + } + + static void checkDsaKeyMatch2(DSAPrivateKey priKey, DSAPublicKey pubKey) { + DSAParams params = priKey.getParams(); + BigInteger p = params.getP(); + BigInteger q = params.getQ(); + BigInteger g = params.getG(); + BigInteger x = priKey.getX(); + BigInteger y = pubKey.getY(); + log.info("Is p a prime? " + p.isProbablePrime(200)); + log.info("Is q a prime? " + q.isProbablePrime(200)); + BigInteger subtract = p.subtract(BigInteger.ONE).mod(q) + log.info("Is p-1 mod q == 0? " + subtract); + assert subtract==BigInteger.ZERO + BigInteger modPow = g.modPow(q, p); + log.info("Is g**q mod p == 1? " + modPow); + assert modPow == BigInteger.ONE + log.info("Is q > x? " + (q.compareTo(x) == 1)); + assert q >x + BigInteger modPow2 = g.modPow(x, p) + log.info("Is g**x mod p == y? " + modPow2.equals(y)); + assert modPow2 == y + } + + static void checkDsaKeyMatch(DSAPrivateKey dsaPrivateKey, DSAPublicKey dsaPublicKey) { + assert dsaPrivateKey.getParams() == dsaPublicKey.getParams() + } + + static void checkRsaKeyMatch3(RSAPrivateKey rsaPrivateKey, RSAPublicKey rsaPublicKey) { + assert rsaPublicKey.getModulus().equals(rsaPrivateKey.getModulus()) + + BigInteger pow = BigInteger.valueOf(2).modPow(rsaPublicKey.getPublicExponent() + .multiply(rsaPrivateKey.getPrivateExponent()).subtract(BigInteger.ONE), + rsaPublicKey.getModulus()); + assert pow == BigInteger.ONE + } + + // TODO works ? + static void checkKeyMatch4(ECKey privateKey, ECKey publicKey) { + assert privateKey.getParams() == publicKey.getParams(); + } + + static void checkRsaKeyMatch1(RSAPrivateKey privateKey, RSAPublicKey publicKey) { + assert privateKey.getModulus() == publicKey.getModulus(); + } + + + static void checkRsaKeyMatch2(RSAPrivateCrtKey privateKey, RSAPublicKey publicKey) { + assert privateKey.getModulus() == publicKey.getModulus(); + assert privateKey.getPublicExponent() == publicKey.getPublicExponent(); + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoader3.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoader3.groovy new file mode 100644 index 00000000..49f3ea1f --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoader3.groovy @@ -0,0 +1,118 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities +import org.apache.commons.codec.binary.Base64 + +import java.security.Key +import java.security.KeyFactory +import java.security.PrivateKey +import java.security.Provider +import java.security.PublicKey +import java.security.Security +import java.security.cert.Certificate +import java.security.cert.CertificateFactory +import java.security.cert.X509Certificate +import java.security.interfaces.ECKey +import java.security.interfaces.RSAPrivateCrtKey +import java.security.interfaces.RSAPrivateKey +import java.security.interfaces.RSAPublicKey +import java.security.spec.PKCS8EncodedKeySpec +import java.security.spec.X509EncodedKeySpec; +import java.util.logging.Logger; + +@CompileStatic +class AsymetricKeyLoader3 { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + + static Key loadKey(byte[] bytes, String type, Provider provider) { + String text = new String(bytes,'UTF8') + List lines = text.readLines() + String firstLine = lines[0] + if (firstLine.contains('BEGIN RSA PRIVATE KEY')) { + String lastLine = lines.last() + assert lastLine.contains('END RSA PRIVATE KEY') + lines.remove(0) + lines.remove(lines.size() - 1) + String string = lines.join('') + byte[] decodeBase64 = Base64.decodeBase64(string) + if (type == null) { + type = KeyType.RSA.name() + } + return loadPrivateKey(decodeBase64, type, provider) + } + if (firstLine.contains('BEGIN DSA PRIVATE KEY')) { + String lastLine = lines.last() + assert lastLine.contains('END DSA PRIVATE KEY') + lines.remove(0) + lines.remove(lines.size() - 1) + String string = lines.join('') + byte[] decodeBase64 = Base64.decodeBase64(string) + if (type == null) { + type = KeyType.DSA.name() + } + return loadPrivateKey(decodeBase64, type, provider) + } + if (firstLine.contains('BEGIN PUBLIC KEY')) { + String lastLine = lines.last() + assert lastLine.contains('END PUBLIC KEY') + lines.remove(0) + lines.remove(lines.size() - 1) + String string = lines.join('') + byte[] decodeBase64 = Base64.decodeBase64(string) + return loadPublicKey(decodeBase64, type, provider) + } + throw new Exception("unkown type") + } + + static PrivateKey loadPrivateKey(byte[] keyBytes, String keyType, Provider provider) { + if(keyType==null){ + throw new Exception("set key keyType") + } + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory kf; + if (provider == null) { + kf = KeyFactory.getInstance(keyType); + } else { + kf = KeyFactory.getInstance(keyType, provider); + } + PrivateKey privateKey = kf.generatePrivate(spec); + return privateKey; + } + + static PublicKey loadPublicKey(byte[] keyBytes, String type, Provider provider) { + X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); + KeyFactory kf; + if (provider == null) { + kf = KeyFactory.getInstance(type); + } else { + kf = KeyFactory.getInstance(type, provider); + } + PublicKey publicKey = kf.generatePublic(spec); + return publicKey; + } + + static X509Certificate loadX509Certificate(byte[] bytes){ + CertificateFactory fact = CertificateFactory.getInstance("X.509"); + ByteArrayInputStream bais =new ByteArrayInputStream(bytes) + X509Certificate certificate = fact.generateCertificate(bais) as X509Certificate; + bais.close() + return certificate + } + + + + + static Provider[] receiveProviders() { + return Security.getProviders(); + } + + static Map> getSecurityServices() { + return JrrUtilities.getSecurityServices(); + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderAny.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderAny.groovy new file mode 100644 index 00000000..8850a72b --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderAny.groovy @@ -0,0 +1,122 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import com.jcraft.jsch.JSch +import com.jcraft.jsch.KeyPair +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.security.Key +import java.security.Provider +import java.security.Security; +import java.util.logging.Logger; + +@CompileStatic +class AsymetricKeyLoaderAny { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static boolean bcRegistered = false + + static Object loadKeyAny(File f, KeyType type, Boolean isPrivateKey) { + if (isPrivateKey == null) { + String name = f.getName() + if (name == 'id_dsa') { + isPrivateKey = true + if (type == null) { + type = KeyType.DSA + } + } + if (name == 'id_rsa') { + isPrivateKey = true + if (type == null) { + type = KeyType.RSA + } + } + if (name.endsWith('.pub')) { + isPrivateKey = false + } + } + String type2; + if (type != null) { + type2 = type.name(); + } + return loadKeyAny(f.bytes, type2, isPrivateKey) + } + + static Object loadKeyAny(byte[] bytes, String type, Boolean isPrivateKey) { + if (!bcRegistered) { + bcRegistered = true; + Provider provider = JavaSecurityProviders.BC.className.newInstance3() as Provider; + Security.addProvider(provider); + } + + if (isPrivateKey == null || !isPrivateKey) { + try { + return AsymetricKeyLoader3.loadX509Certificate(bytes) + } catch (Throwable e) { + log.warn("failed load x509 certificate", e) + } + } + try { + return AsymetricKeyLoader3.loadKey(bytes, type, null); + } catch (Throwable e) { + log.warn("failed load key using ${AsymetricKeyLoader3.getSimpleName()}", e) + } + + if (isPrivateKey == null) { + try { + return AsymetricKeyLoaderSshtools.loadPrivateKeyUseful(bytes, null) + } catch (Throwable e) { + log.warn("failed load sshtool private", e) + } + try { + return AsymetricKeyLoaderSshtools.loadPublicKeyUseful(bytes) + } catch (Throwable e) { + log.warn("failed load sshtool public", e) + } + + } else { + try { + if (isPrivateKey) { + return AsymetricKeyLoaderSshtools.loadPrivateKeyUseful(bytes, null) + } else { + return AsymetricKeyLoaderSshtools.loadPublicKeyUseful(bytes) + } + } catch (Throwable e) { + log.warn("failed load sshtool common", e) + } + } + try { + return AsymetricKeyBC2.loadKeyBcUseful(bytes) + } catch (Throwable e) { + log.warn("failed load bc KeyPair ", e) + } + if (isPrivateKey == null) { + try { + JSch jSch = new JSch() + return KeyPair.load(jSch, bytes, null) + } catch (Throwable e) { + log.warn("failed load jsch private ", e) + } + try { + JSch jSch = new JSch() + return KeyPair.load(jSch, null, bytes) + } catch (Throwable e) { + log.warn("failed load jsch public ", e) + } + } else { + JSch jSch = new JSch() + try { + if (isPrivateKey) { + return KeyPair.load(jSch, bytes, null) + } else { + return KeyPair.load(jSch, null, bytes) + } + } catch (Throwable e) { + log.warn("failed load jsch common ", e) + } + } + + return null + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderJsch.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderJsch.groovy new file mode 100644 index 00000000..e520efce --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderJsch.groovy @@ -0,0 +1,31 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import com.jcraft.jsch.JSch +import com.jcraft.jsch.KeyPair +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.util.logging.Logger + +@CompileStatic +class AsymetricKeyLoaderJsch { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static KeyPair load(JSch jSch, File privateKeyF, File publicKeyF) { + if (jSch == null) { + jSch = new JSch(); + } + byte[] privateKeyB; + byte[] publicKeyB; + if (privateKeyF != null) { + privateKeyB = privateKeyF.bytes + } + if (publicKeyF != null) { + publicKeyB = publicKeyF.bytes + } + KeyPair keyPair = KeyPair.load(jSch, privateKeyB, publicKeyB) + return keyPair; + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderSshtools.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderSshtools.groovy new file mode 100644 index 00000000..e1e96714 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/AsymetricKeyLoaderSshtools.groovy @@ -0,0 +1,67 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import com.sshtools.publickey.SshPrivateKeyFile +import com.sshtools.publickey.SshPrivateKeyFileFactory +import com.sshtools.publickey.SshPublicKeyFile +import com.sshtools.publickey.SshPublicKeyFileFactory +import com.sshtools.ssh.components.SshKeyPair +import com.sshtools.ssh.components.SshPrivateKey +import com.sshtools.ssh.components.SshPublicKey +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.security.PrivateKey +import java.security.PublicKey; +import java.util.logging.Logger; + + +// see also com.trilead.ssh2.crypto.PEMDecoder.decode +@CompileStatic +class AsymetricKeyLoaderSshtools { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static PrivateKey loadPrivateKeyUseful(byte[] f, String passprase){ + SshPrivateKey key = loadPrivateKey2(f, passprase) + return JrrClassUtils.getFieldValue(key,'prv') as PrivateKey + } + + static SshPrivateKey loadPrivateKey2(byte[] f,String passprase){ + SshKeyPair sshKeyPair = loadPrivateKey(f,passprase) + SshPrivateKey privateKey = sshKeyPair.getPrivateKey() + return privateKey; + } + + static SshKeyPair loadPrivateKey(byte[] f,String passprase){ + SshPrivateKeyFile parse = SshPrivateKeyFileFactory.parse(f) + SshKeyPair sshKeyPair = parse.toKeyPair(passprase); + return sshKeyPair + } + + static PublicKey loadPublicKeyUseful(byte[] f){ + // TODO use instance of private key + SshPublicKey key = loadPublicKey(f) + try { + PublicKey publicKey = JrrClassUtils.getFieldValue(key, 'pubKey') as PublicKey; + return publicKey + }catch(NoSuchFieldException e){ + log.info("seems field not exit pubKey",e) + } + try { + PublicKey publicKey = JrrClassUtils.getFieldValue(key, 'pubkey') as PublicKey; + return publicKey + }catch(NoSuchFieldException e){ + log.info("seems field not exit pubkey",e) + } + PublicKey publicKey = JrrClassUtils.getFieldValue(key, 'pub') as PublicKey; + return publicKey + } + + static SshPublicKey loadPublicKey(byte[] bytes){ + SshPublicKeyFile sshPublicKeyFile = SshPublicKeyFileFactory.parse(bytes) + SshPublicKey publicKey = sshPublicKeyFile.toPublicKey() + return publicKey; + } + + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/CertificateChecker.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/CertificateChecker.groovy new file mode 100644 index 00000000..4c627df7 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/CertificateChecker.groovy @@ -0,0 +1,158 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.nonjdk.FileRotate +import org.apache.commons.lang3.SystemUtils + +import java.security.KeyStore +import java.security.Principal +import java.security.cert.Certificate +import java.security.cert.X509Certificate; +import java.util.logging.Logger; + +@CompileStatic +class CertificateChecker { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static String customTrustedStorePath = 'javax.net.ssl.trustStore' + public static String defaultJksPassword = 'changeit' + public KeyStore keyStore1; + + CertificateChecker() { + this(loadDefaultKetStoreJks(getDefaultJavaCertPath(),defaultJksPassword)) + // more props see in + new ClRef('org.apache.http.impl.client.HttpClientBuilder') + } + + + CertificateChecker(KeyStore keyStore) { + this.keyStore1 = keyStore + if(keyStore==null){ + throw new NullPointerException('key store is null') + } + } + + static File getDefaultJavaCertPath(){ + File javaHome = SystemUtils.getJavaHome() + File file = new File(javaHome, 'lib/security/cacerts') + assert file.exists() + return file + } + + static KeyStore loadDefaultKetStoreJks(File file, String password) { + assert file.exists() + KeyStore keyStore = KeyStore.getInstance('JKS') + BufferedInputStream inputStream = file.newInputStream() + try { + keyStore.load(inputStream, password.toCharArray()) + } catch (Exception e) { + try { + inputStream.close() + } catch (Exception e2) { + log.info2(e2) + } + throw e; + } + return keyStore; + } + + void addCertificate(X509Certificate certificate){ + String commonName = getCommonName(certificate.getSubjectDN()) + keyStore1.setCertificateEntry(commonName,certificate); + } + + + void saveKeyStore(File file, String password) { + FileRotate.rotateFile(file,20) + DataOutputStream outputStream = file.newDataOutputStream() + try { + keyStore1.store(outputStream, password.toCharArray()) + } catch (Exception e) { + try { + outputStream.flush() + outputStream.close() + } catch (Exception e2) { + log.info2(e2) + } + throw e; + } + + } + + + X509Certificate getCertificateFromKeyStoreByName(String neededCommonName) { + X509Certificate matched; + List aliases = keyStore1.aliases().toList(); + aliases.each { + try { + Certificate certificate1 = keyStore1.getCertificate(it) + if (certificate1 instanceof X509Certificate) { + X509Certificate x509Certificate = (X509Certificate) certificate1; + if (isGoodCertificate(it, x509Certificate, neededCommonName)) { + if (matched == null) { + matched = x509Certificate; + } else { + throw new Exception("found many matched certificates : ${certificate1} , ${matched}") + } + } + } + }catch(Exception e){ + log.info "failed iterate over ${it} : ${e}" + throw e; + } + + } + return matched; + } + + boolean isGoodCertificate(String alias, X509Certificate certificate, String neededCommonName) { + if (certificate == null) { + return false + } + + X509Certificate x509Certificate = (X509Certificate) certificate; + Principal subjectDN = x509Certificate.getSubjectDN(); + String commonName1 = getCommonName(subjectDN) + return commonName1 == neededCommonName + } + + void checkCertificate(X509Certificate certificate) { + String issuerDn = getCommonName(certificate.getIssuerDN()) + X509Certificate certCheckBy = getCertificateFromKeyStoreByName(issuerDn) + if (certCheckBy == null) { + throw new Exception("certificate not found : ${issuerDn}") + } + certificate.verify(certCheckBy.getPublicKey()) + } + + + String getCommonName(Principal subjectDN) { + String string = subjectDN.toString(); + if (string == null) { + return null + } + String cn; + List tokenizeL = string.tokenize(',') + tokenizeL.each { + String el1 = it; + if (el1.contains('=')) { + List sepp = el1.trim().tokenize('=') + if (sepp.size() == 2 && sepp[0] == 'CN') { + String cnValue = sepp[1] + if (cn == null) { + cn = cnValue + } else { + if (cn != cnValue) { + throw new Exception("duplicated cn : ${cnValue} , ${cn} ") + } + } + } + } + } + return cn; + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/CipherMode.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/CipherMode.groovy new file mode 100644 index 00000000..c9a05909 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/CipherMode.groovy @@ -0,0 +1,24 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import javax.crypto.Cipher; +import java.util.logging.Logger; + +@CompileStatic +enum CipherMode { + + + encrypt(Cipher.ENCRYPT_MODE), + wrap(Cipher.WRAP_MODE), + unwrap(Cipher.UNWRAP_MODE), + decrypt(Cipher.DECRYPT_MODE); + + + int javaMode; + + CipherMode(int javaMode) { + this.javaMode = javaMode + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/EcPrivateKeyChecker.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/EcPrivateKeyChecker.groovy new file mode 100644 index 00000000..a1973451 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/EcPrivateKeyChecker.groovy @@ -0,0 +1,106 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.security.interfaces.ECPrivateKey +import java.security.interfaces.ECPublicKey +import java.security.spec.ECField +import java.security.spec.ECFieldF2m +import java.security.spec.ECFieldFp +import java.security.spec.ECParameterSpec +import java.security.spec.ECPoint +import java.security.spec.EllipticCurve; +import java.util.logging.Logger; + +// https://github.com/str4d/ed25519-java +// https://stackoverflow.com/questions/24121801/how-to-verify-if-the-private-key-matches-with-the-certificate +@CompileStatic +class EcPrivateKeyChecker { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static void check1( ECPrivateKey privateKey,ECPublicKey publicKey) { + ECParameterSpec pkSpec = publicKey.getParams(), skSpec = privateKey.getParams(); + EllipticCurve skCurve = skSpec.getCurve(), pkCurve = pkSpec.getCurve(); + ECField skField = skCurve.getField(), pkField = pkCurve.getField(); + BigInteger skA = skCurve.getA(), skB = skCurve.getB(); + if (pkSpec != skSpec // + && (pkSpec.getCofactor() != skSpec.getCofactor() // + || !pkSpec.getOrder().equals(skSpec.getOrder()) // + || !pkSpec.getGenerator().equals(skSpec.getGenerator()) // + || pkCurve != skCurve // + && (!pkCurve.getA().equals(skA) // + || !pkCurve.getB().equals(skB) // + || skField.getFieldSize() != pkField.getFieldSize()))) { + assert false + } + + + ECPoint w = publicKey.getW(); + BigInteger x = w.getAffineX(), y = w.getAffineY(); + if (skField instanceof ECFieldFp) { + BigInteger skP = ((ECFieldFp) skField).getP(); + if(pkField instanceof ECFieldFp && skP.equals(((ECFieldFp) pkField).getP()) ){ + int res12 =y.pow(2).subtract(x.pow(3)).subtract(skA.multiply(x)).subtract(skB).mod(skP).signum() + assert res12 == 0 + } + assert false + + } + if (skField instanceof ECFieldF2m) { + int m = ((ECFieldF2m) skField).getM(); + BigInteger rp = ((ECFieldF2m) skField).getReductionPolynomial(); + if (!(pkField instanceof ECFieldF2m) || m != ((ECFieldF2m) skField).getM() || !rp.equals(((ECFieldF2m) skField).getReductionPolynomial())) { + assert false + } + BigInteger x2 = f2mReduce(f2mMultiply(x, x), rp, m); + int res = f2mReduce(f2mSum(f2mMultiply(y, y), f2mMultiply(x, y), f2mMultiply(x, x2), f2mMultiply(skA, x2), skB), rp, m).signum(); + assert res == 0 + } + assert false + } + + + public static final BigInteger f2mSum(BigInteger... values) { + if (values.length == 0) + return BigInteger.ZERO; + BigInteger result = values[0]; + for (int i = values.length - 1; i > 0; i--) + result = result.xor(values[i]); + return result; + } + + + public static final BigInteger f2mAdd(BigInteger a, BigInteger b) { + return a.xor(b); + } + + + public static final BigInteger f2mSubtract(BigInteger a, BigInteger b) { + return a.xor(b); + } + + + public static final BigInteger f2mMultiply(BigInteger a, BigInteger b) { + BigInteger result = BigInteger.ZERO, sparse, full; + if (a.bitCount() > b.bitCount()) { + sparse = b; + full = a; + } else { + sparse = b; + full = a; + } + for (int i = sparse.bitLength(); i >= 0; i--) + if (sparse.testBit(i)) + result = result.xor(full.shiftLeft(i)); + return result; + } + + + public static final BigInteger f2mReduce(BigInteger input, BigInteger reductionPolynom, int bitLength) { + while (input.bitLength() > bitLength) + input = input.xor(reductionPolynom.shiftLeft(input.bitLength() - reductionPolynom.bitLength())); + return input; + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/EncDec.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/EncDec.groovy new file mode 100644 index 00000000..9d584540 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/EncDec.groovy @@ -0,0 +1,70 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.JrrGroovyScriptRunner +import net.sf.jremoterun.utilities.nonjdk.crypto.CipherMode +import org.apache.commons.io.IOUtils +import org.bouncycastle.jce.provider.BouncyCastleProvider + +import javax.crypto.Cipher +import javax.crypto.CipherInputStream +import javax.crypto.SecretKey +import javax.crypto.SecretKeyFactory +import javax.crypto.spec.IvParameterSpec +import javax.crypto.spec.PBEKeySpec +import javax.crypto.spec.SecretKeySpec +import java.security.Security +import java.util.logging.Logger + +@CompileStatic +class EncDec { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass() + + EncInfo encInfo + + static EncInfo loadConfig(File encInfoFile) { + JrrGroovyScriptRunner r = new JrrGroovyScriptRunner() + EncInfo encInfo2 = new EncInfo() + r.loadSettingsWithParam(encInfoFile, encInfo2) + return encInfo2; + } + + void encDec1(File inf, File outF, CipherMode mode, File encInfo) { + EncInfo encInfo2 = loadConfig(encInfo) + encDec2(inf, outF, mode, encInfo2) + } + + void encDec2(File inf, File outF, CipherMode mode, EncInfo encInfo) { + assert inf != outF + this.encInfo = encInfo + Security.addProvider(new BouncyCastleProvider()) + SecretKey key2 = getKey() + Cipher cipher = Cipher.getInstance(encInfo.cipherAlgo, encInfo.provider) + IvParameterSpec spec = new IvParameterSpec(encInfo.iv.toByteArray()) +// cipher.init(mode, key2) + cipher.init(mode.javaMode, key2, spec) + CipherInputStream stream = new CipherInputStream(inf.newInputStream(), cipher) + BufferedOutputStream stream1 = outF.newOutputStream() + IOUtils.copy(stream, stream1) + stream1.flush() + stream.close() + stream1.close() +// log.info new JavaBeanStore().saveS(encInfo) + log.info "finished" + } + + SecretKey getKey() { + String pass = encInfo.pass +// log.info "pass = ${pass}" + PBEKeySpec keySpec = new PBEKeySpec(pass.toCharArray(), encInfo.keySalt.toByteArray(), encInfo.iter, encInfo.keyLen) + SecretKeyFactory skf = SecretKeyFactory.getInstance(encInfo.keyParam, encInfo.provider) +// log.info skf.getProvider().getName() + SecretKey secret = skf.generateSecret(keySpec) + SecretKey secret2 = new SecretKeySpec(secret.getEncoded(), "AES") + return secret2 + + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/EncInfo.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/EncInfo.groovy new file mode 100644 index 00000000..f67cd57b --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/EncInfo.groovy @@ -0,0 +1,46 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.store.JavaBean; + +import java.util.logging.Logger; + +@CompileStatic +class EncInfo implements JavaBean { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + String keyParam; + BigInteger iv; + BigInteger keySalt; + String pass; + int iter; + int keyLen; + String cipherAlgo; + String provider; + + public static EncInfo createBasic() { + EncInfo b = new EncInfo() + +// b.keyParam = 'PBEWithHmacSHA256AndAES_256'; + b.keyParam = 'PBEWithHmacSHA128AndAES_128'; + //b.iv + //b.keySalt; + //b.pass; + b.iter = 128; + b.keyLen = 128; + b.cipherAlgo = 'AES/CBC/PKCS5Padding'; + b.provider = 'SunJCE'; + return b; + } + + + static BigInteger createBytes(int length) { + byte[] b = new byte[16]; + new Random().nextBytes(b) + return new BigInteger(b); + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/JavaSecurityProviders.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/JavaSecurityProviders.groovy new file mode 100644 index 00000000..18391694 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/JavaSecurityProviders.groovy @@ -0,0 +1,27 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.ClRef + +import java.security.Security; +import java.security.Provider; + + +@CompileStatic +enum JavaSecurityProviders { + + SunJCE(null),BC(new ClRef('org.bouncycastle.jce.provider.BouncyCastleProvider')), + ; + + public ClRef className; + + JavaSecurityProviders(ClRef className) { + this.className = className + } + + Provider loadProvider(){ + Security.getProvider(name()); + } + + +} \ No newline at end of file diff --git a/src/net/sf/jremoterun/utilities/nonjdk/crypto/KeyType.groovy b/src/net/sf/jremoterun/utilities/nonjdk/crypto/KeyType.groovy new file mode 100644 index 00000000..48c3b025 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/crypto/KeyType.groovy @@ -0,0 +1,14 @@ +package net.sf.jremoterun.utilities.nonjdk.crypto + +import groovy.transform.CompileStatic; + + +@CompileStatic +enum KeyType { + + RSA, + DSA, + // works ?? + ECDSA, + ; +} \ No newline at end of file diff --git a/src/net/sf/jremoterun/utilities/nonjdk/cvsutils/CsvComparator.groovy b/src/net/sf/jremoterun/utilities/nonjdk/cvsutils/CsvComparator.groovy index efaeb139..fea25f8f 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/cvsutils/CsvComparator.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/cvsutils/CsvComparator.groovy @@ -6,12 +6,21 @@ import net.sf.jremoterun.utilities.JrrClassUtils import java.util.logging.Logger + @CompileStatic abstract class CsvComparator { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + /** + * Columns id starts with 0 + */ List skipColumns = [] + + + /** + * Columns id starts with 0 + */ List columnsIds = [] CSVReader csvReader @@ -24,7 +33,7 @@ abstract class CsvComparator { abstract void writeLine(List line) - abstract customLineProcessing(List line2) + abstract List customLineProcessing(List line2) /** @@ -32,9 +41,10 @@ abstract class CsvComparator { */ void processLines() { createReader() - assert csvReader!=null + assert csvReader != null readHeader() headerRead() + skipColumns = skipColumns.sort().reverse() doChecks() currentLine = header processLine() @@ -49,7 +59,12 @@ abstract class CsvComparator { onDiffColumnCount() } printProgressIfNeeded() - processLine() + try { + processLine() + } catch (Throwable e) { + log.info "failed process ${currentLine} : ${e}" + throw e + } } } @@ -87,12 +102,12 @@ abstract class CsvComparator { } void processLine() { - List line = currentLine + final List line = currentLine List line2 = new ArrayList<>(line) - customLineProcessing(line2) + line2 = customLineProcessing(line2) List idColumns = columnsIds.collect { line.get(it) } skipColumns.collect { line2.remove(it) } - line2.addAll(0 , idColumns) + line2.addAll(0, idColumns) writeLine(line2) } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/cvsutils/CsvNormalizer.groovy b/src/net/sf/jremoterun/utilities/nonjdk/cvsutils/CsvNormalizer.groovy new file mode 100644 index 00000000..b297a2d1 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/cvsutils/CsvNormalizer.groovy @@ -0,0 +1,71 @@ +package net.sf.jremoterun.utilities.nonjdk.cvsutils + +import com.opencsv.CSVParserBuilder +import com.opencsv.CSVReaderBuilder +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +abstract class CsvNormalizer extends CsvComparator { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public File inF; + public File outF; + public Reader reader + public Writer writer + public static String fileSuffixNormalize = '.normalize'; + + /** + * main method + */ + void normalizeFile(File inF) { + assert inF.exists() + this.inF = inF + assignOutFile() + processLines() + csvReader.close() + writer.flush() + writer.close() + } + + void assignOutFile() { + assert !inF.getName().endsWith(fileSuffixNormalize) + outF = new File(inF.getAbsolutePath() + fileSuffixNormalize); + if(outF.exists()) { + assert outF.canWrite() + }else { + File getParentFile = outF.getParentFile(); + assert getParentFile.canWrite() + } + } + + @Override + void createReader() { + reader = inF.newReader() + csvReader = createReaderBuilder().build(); + writer = outF.newWriter() + } + + + CSVReaderBuilder createReaderBuilder() { + return new CSVReaderBuilder(reader).withCSVParser(createParserBuilder().build()) + } + + + /** + * Set separator here + */ + CSVParserBuilder createParserBuilder() { + return new CSVParserBuilder(); + } + + String getOutSeparator() { + return Character.toString(csvReader.getParser().getSeparator()) + } + + @Override + void writeLine(List line) { + writer.println(line.join(getOutSeparator())); + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/decompiler/DecompilerAddFiles.groovy b/src/net/sf/jremoterun/utilities/nonjdk/decompiler/DecompilerAddFiles.groovy index b1f397c4..4cc7cc0d 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/decompiler/DecompilerAddFiles.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/decompiler/DecompilerAddFiles.groovy @@ -30,10 +30,19 @@ class DecompilerAddFiles extends AddFilesToClassLoaderGroovy{ void addRtJar(){ - File javaHome = SystemUtils.getJavaHome() - assert javaHome.exists() - File rtJar = javaHome.child('lib/rt.jar') - add rtJar + File javaHome = SystemUtils.getJavaHome(); + assert javaHome.exists(); + File rtJar = javaHome.child('lib/rt.jar'); + add( rtJar); + } + + void addJfrJarsIfExists(){ + File javaHome = SystemUtils.getJavaHome(); + assert javaHome.exists(); + File jfrJar = javaHome.child('lib/jfr.jar'); + if(jfrJar.exists()) { + add(jfrJar); + } } void addToolsJar(){ @@ -46,6 +55,7 @@ class DecompilerAddFiles extends AddFilesToClassLoaderGroovy{ void addAllJdkJars(){ addRtJar() + addJfrJarsIfExists() addToolsJar() } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/depanalise/AddFilesToJavasistPool.groovy b/src/net/sf/jremoterun/utilities/nonjdk/depanalise/AddFilesToJavasistPool.groovy index 9b37b061..44ca27a2 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/depanalise/AddFilesToJavasistPool.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/depanalise/AddFilesToJavasistPool.groovy @@ -24,7 +24,7 @@ class AddFilesToJavasistPool extends AddFilesToClassLoaderGroovy { @Override void addFileImpl(File file) throws Exception { - classPool.appendClassPath(file.absolutePath); + classPool.appendClassPath(file.getAbsolutePath()); } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/depanalise/DependencyChecker.groovy b/src/net/sf/jremoterun/utilities/nonjdk/depanalise/DependencyChecker.groovy index aedc5f3d..80006094 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/depanalise/DependencyChecker.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/depanalise/DependencyChecker.groovy @@ -11,6 +11,9 @@ import net.sf.jremoterun.utilities.nonjdk.classpath.calchelpers.ClassPathCalcula import java.util.logging.Logger +/** + * Doesn't check that method exists + */ @CompileStatic class DependencyChecker { diff --git a/src/net/sf/jremoterun/utilities/nonjdk/disktest/DiskPerformanceTester.groovy b/src/net/sf/jremoterun/utilities/nonjdk/disktest/DiskPerformanceTester.groovy new file mode 100644 index 00000000..8b778d10 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/disktest/DiskPerformanceTester.groovy @@ -0,0 +1,194 @@ +package net.sf.jremoterun.utilities.nonjdk.disktest + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.util.logging.Level +import java.util.logging.Logger + +@CompileStatic +class DiskPerformanceTester { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + // Arguments to be filled in before starting + private final int fileCount; + private final int fileSize; + private final File dirPath; + public Random r = new Random(); + + private final byte[][] filesInMemory; + private RandomAccessFile[] randomAccessFiles; + + public long totalReadFailures = 0; + public long totalWriteFailures = 0; + public long totalOtherFailures = 0; + public long totalWrites = 0; + public long totalReads = 0; + + public long sleepBetweenIterations = 5000; + public long sleepOnFailure = 1000; + public volatile boolean continueRun = true; + public volatile int iteration = 1; + public volatile int maxIteration = 0; // mean unlimited + public HashSet createdFiles= new HashSet<>(); + + + DiskPerformanceTester(int fileCount, int fileSize, File dirPath) { + this.fileCount = fileCount + this.fileSize = fileSize + this.dirPath = dirPath + println("Allocating memory..."); + filesInMemory = new byte[fileCount][fileSize]; + } + + + void start() throws InterruptedException { + println("OK"); + + + while (continueRun) { + if (maxIteration > 0 && iteration > maxIteration) { + break + } + onIteration(iteration); + Thread.sleep(sleepBetweenIterations); + iteration++; + } + closeAndDelete() + log.info "finish" + + } + + void closeAndDelete() { + randomAccessFiles.toList().each { it.close(); } + createdFiles.each { it.delete() } + } + + protected void onIteration(final int iteration) throws InterruptedException { + printSummary(); + //TODO: cleanup previous iteration here + + println("Iteration " + iteration); + + println("Determining file content..."); + for (int i = 0; i < fileCount; i++) { + r.nextBytes(filesInMemory[i]); + } + println("OK"); + + print("Creating files for writing..."); + randomAccessFiles = new RandomAccessFile[fileCount]; + for (int i = 0; i < fileCount; i++) { + try { + File childFile = new File(dirPath, "DiskTester" + (i + 1) + ".dat"); + createdFiles.add(childFile) + randomAccessFiles[i] = new RandomAccessFile(childFile, "rws"); + } catch (FileNotFoundException exc) { + println("(!!!) FAILED to create file " + (i + 1) + "!"); + totalOtherFailures++; + throw exc; + } + } + println("OK"); + + println("Writing file content..."); + long start = System.currentTimeMillis(); + for (int i = 0; i < fileCount; i++) { + try { + randomAccessFiles[i].seek(0); + } catch (IOException exc) { + println("(!!!) FAILED to seek to position 0 in file " + (i + 1) + "!"); + totalOtherFailures++; + throw exc; + } + + totalWrites += 1; + try { + randomAccessFiles[i].write(filesInMemory[i]); + randomAccessFiles[i].getFD().sync(); + randomAccessFiles[i].close(); + } catch (IOException exc) { + println("(!!!) FAILED to write to file " + (i + 1) + "!"); + totalWriteFailures++; + throw exc; + } + } + long end = System.currentTimeMillis(); + println("OK"); + println("Writing took " + (end - start) + "ms"); + + println("Re-opening files for reading..."); + randomAccessFiles = new RandomAccessFile[fileCount]; + for (int i = 0; i < fileCount; i++) { + try { + File childFile = new File(dirPath, "DiskTester" + (i + 1) + ".dat"); + randomAccessFiles[i] = new RandomAccessFile(childFile, "r"); + } catch (FileNotFoundException exc) { + println("(!!!) FAILED to open file " + (i + 1) + "!"); + totalOtherFailures++; + throw exc; + } + } + println("OK"); + + // Read + println("Reading file content..."); + start = System.currentTimeMillis(); + for (int i = 0; i < fileCount; i++) { + try { + randomAccessFiles[i].seek(0); + } catch (IOException exc) { +// println("(!!!) FAILED to seek to position 0 in file " + (i+1) + "!"); + totalOtherFailures++; +// exc.printStackTrace(); + log.log(Level.SEVERE, "(!!!) FAILED to seek to position 0 in file " + (i + 1) + "!", exc) + continue; + } + + byte[] readBuffer = new byte[4096]; + int bytesRead = -1; + int placeInFile = 0; + try { + while ((bytesRead = randomAccessFiles[i].read(readBuffer)) != -1) { + totalReads += bytesRead; + + // Examine the bytes! + for (int b = 0; b < bytesRead; b++) { + if (filesInMemory[i][placeInFile] != readBuffer[b]) { + println("(!!!) FAILED! Should have been " + filesInMemory[i][placeInFile] + " but got " + readBuffer[b] + " instead!"); + totalReadFailures++; + Thread.sleep(sleepOnFailure); + } + placeInFile++; + } + } + } catch (IOException exc) { + totalReadFailures++; + log.log(Level.SEVERE, "(!!!) FAILED! Could not read byte!", exc) + } + + // End of file reached but was that correct? + if (placeInFile < fileSize) { + println("(!!!) FAILED! Premature end of file at " + placeInFile + " when it should have been at " + fileSize); + totalReadFailures++; + Thread.sleep(sleepOnFailure); + } + } + end = System.currentTimeMillis(); + println("OK"); + println("Reading took " + (end - start) + "ms"); + } + + + public void printSummary() { + println("--------------------Summary--------------------"); + println("Total Reads = " + totalReads); + println("Total Read Failures = " + totalReadFailures); + println("Total Writes = " + totalWrites); + println("Total Write Failures = " + totalWriteFailures); + println("Total Other Failures = " + totalOtherFailures); + } + + +} \ No newline at end of file diff --git a/src/net/sf/jremoterun/utilities/nonjdk/disktest/DiskPerformanceTesterWrapper.groovy b/src/net/sf/jremoterun/utilities/nonjdk/disktest/DiskPerformanceTesterWrapper.groovy new file mode 100644 index 00000000..d5781ae6 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/disktest/DiskPerformanceTesterWrapper.groovy @@ -0,0 +1,87 @@ +package net.sf.jremoterun.utilities.nonjdk.disktest + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +// https://github.com/philiprodriguez/DiskTester +@CompileStatic +class DiskPerformanceTesterWrapper { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + // Arguments to be filled in before starting + private static int fileCount; + private static int fileSize; + private static String dirPath = "./"; + + // Other stuff + private static final Scanner scan = new Scanner(System.in); + + static void main(String[] args) throws InterruptedException { + if (args.length > 0) { + boolean fileCountSatisfied = false; + boolean fileSizeSatisfied = false; + + for (int a = 0; a < args.length; a++) { + if (args[a].equals("-fileSize")) { + if (isPositiveIntegerString(args[a+1])) { + fileSize = Integer.parseInt(args[a+1]); + a++; + fileSizeSatisfied = true; + } else { + System.out.println("File size must be a positive integer."); + } + } else if (args[a].equals("-fileCount")) { + if (isPositiveIntegerString(args[a+1])) { + fileCount = Integer.parseInt(args[a+1]); + a++; + fileCountSatisfied = true; + } else { + System.out.println("File count must be a positive integer."); + } + } else if (args[a].equals("-dirPath")) { + dirPath = args[a+1]; + a++; + if (!dirPath.endsWith("/")) + dirPath += "/"; + } else { + System.out.println("Illegal argument at position " + a + ": " + args[0]); + printUsage(); + System.exit(1); + } + } + + if (!(fileCountSatisfied && fileSizeSatisfied)) { + System.out.println("One or more required arguments unsatisfied."); + printUsage(); + System.exit(1); + } + } else { + printUsage(); + + System.out.println("Enter the desired file size to test with:"); + fileSize = scan.nextInt(); + System.out.println("Enter the desired file count to test with:"); + fileCount = scan.nextInt(); + System.out.println("Enter the desired working directory:"); + scan.nextLine(); + dirPath = scan.nextLine(); + } + new DiskPerformanceTester(fileCount,fileSize,new File(dirPath)); + } + + private static boolean isPositiveIntegerString(String s) { + return s.matches("[0-9]+") && s.charAt(0) != '0'; + } + + private static void printUsage() { + System.out.println("USAGE:"); + System.out.println("java DiskTester -fileSize (size in bytes) -fileCount (count integer) [-dirPath (path to working directory)]"); + } + + private static void prepareArguments(String[] args) { + + } + +} \ No newline at end of file diff --git a/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/LessDownloader.groovy b/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/LessDownloader.groovy index e0765933..8d2e559c 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/LessDownloader.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/LessDownloader.groovy @@ -2,25 +2,31 @@ package net.sf.jremoterun.utilities.nonjdk.downloadutils import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs import java.util.logging.Logger -@Deprecated + @CompileStatic class LessDownloader { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - private static URL url = new URL("http://netix.dl.sourceforge.net/project/gnuwin32/less/394/less-394-bin.zip") + // https://sourceforge.net/projects/gnuwin32/files/less/394/ - doesn't work + private static URL url = new URL("https://steve.fi/Software/less/less-332.zip") + + public static FileChildLazyRef lessCycle = GitSomeRefs.sshConsole.childL("lesscycle.bat") + static volatile File lessCmd public static File lessViewer; - static File getWinLessViewer(){ - return GitReferences.sshConsole.getSpecOnly().resolveToFile().child("lesscycle.bat") + static FileChildLazyRef getWinLessViewer(){ + return lessCycle } @@ -34,7 +40,7 @@ class LessDownloader { private static File init2() { File unzip = UrlDownloadUtils3.getUrlDownloadUtils().downloadUrlAndUnzip(url) - File lessCmd = new File(unzip, "bin/less.exe") + File lessCmd = new File(unzip, "less-332/Binaries/less.exe") assert lessCmd.exists() return lessCmd } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/UrlDownloadUtils3.groovy b/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/UrlDownloadUtils3.groovy index 84b64fde..f8551db8 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/UrlDownloadUtils3.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/UrlDownloadUtils3.groovy @@ -1,6 +1,8 @@ package net.sf.jremoterun.utilities.nonjdk.downloadutils -import com.github.junrar.extract.ExtractArchive +import com.github.junrar.Junrar +//import com.github.junrar.Archive +//import com.github.junrar.extract.ExtractArchive import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenCommonUtils @@ -72,14 +74,13 @@ class UrlDownloadUtils3 { log.info "already unarchived : ${f2}" return f2; } - String fileName = zipFile.name + String fileName = zipFile.getName() if (fileName.endsWith('.rar')) { // https://github.com/edmund-wagner/junrar // https://github.com/jukka/java-unrar // https://github.com/Albertus82/JUnRAR // https://github.com/asm-labs/junrar - ExtractArchive extractArchive = new ExtractArchive(); - extractArchive.extractArchive(zipFile, f2); + Junrar.extract(zipFile, f2); return f2 } FileType fileType = FileType.get(zipFile); @@ -89,25 +90,10 @@ class UrlDownloadUtils3 { Archiver archiver = ArchiverFactory.createArchiver(zipFile) archiver.extract(zipFile, f2) - return f2 - } - - - private File downloadUrlAndUnzipDel(URL url) { - File f = downloadUrl(url) - if (f.name.endsWith('.zip')) { - File f2 = new File(unzipDir, mcu.buildDownloadUrlSuffix(url)) - if (f2.exists() && f2.listFiles().length > 0) { - log.info("already unziped ${f2}") - return f2 - } - f2.mkdirs() - assert f2.exists() - ZipUtil.unpack(f, f2) - log.info "unzip done ${f2}" - return f2 + if(!f2.exists()){ + throw new Exception("failed unzip : ${zipFile}") } - return f + return f2 } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/WinptyDownloader.groovy b/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/WinptyDownloader.groovy index 88c5361f..062988b3 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/WinptyDownloader.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/downloadutils/WinptyDownloader.groovy @@ -4,6 +4,7 @@ import com.pty4j.util.PtyUtil import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr import net.sf.jremoterun.utilities.nonjdk.classpath.CustomObjectHandlerImpl import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitReferences import org.apache.commons.io.FileUtils @@ -38,7 +39,7 @@ class WinptyDownloader { File f3 = new File(unzip, "x64/bin") assert f3.exists() assert toDir.mkdirs() - FileUtils.copyDirectory(f3, toDir) + FileUtilsJrr.copyDirectory(f3, toDir) } File checkFIle = new File(toDir, 'winpty.dll') assert checkFIle.exists() @@ -48,13 +49,12 @@ class WinptyDownloader { } static void setPtyLibFolder(File unzip){ - JrrClassUtils.setFieldValue(PtyUtil, 'PTY_LIB_FOLDER', unzip.absolutePath) + JrrClassUtils.setFieldValue(PtyUtil, 'PTY_LIB_FOLDER', unzip.getAbsolutePath()) } static void copyLinuxNativeLibs(File toDir){ - CustomObjectHandlerImpl handler = MavenDefaultSettings.mavenDefaultSettings.customObjectHandler as CustomObjectHandlerImpl - File nativeLibs = handler.resolveRef(GitReferences.pty4jLinuxLibs) - FileUtils.copyDirectory(nativeLibs,toDir) + File nativeLibs = GitReferences.pty4jLinuxLibs.resolveToFile() + FileUtilsJrr.copyDirectory(nativeLibs,toDir) } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/fileloayout/GitWinFilesLayout.groovy b/src/net/sf/jremoterun/utilities/nonjdk/fileloayout/GitWinFilesLayout.groovy new file mode 100644 index 00000000..acd6a7aa --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/fileloayout/GitWinFilesLayout.groovy @@ -0,0 +1,40 @@ +package net.sf.jremoterun.utilities.nonjdk.fileloayout + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +enum GitWinFilesLayout { + + + bashExe('bin/bash.exe'), + lessExe('usr/bin/less.exe'), + findExe('usr/bin/find.exe'), + + binDir('bin/'), + mingwBinDir('mingw64/bin/'), + usrBinDir('usr/bin/'), + ; + + + public String subPath; + + GitWinFilesLayout(String subPath) { + this.subPath = subPath + } + + boolean isDir() { + return subPath.endsWith('/'); + } + + boolean isExecFile(){ + return name().endsWith('exe') + } + + File buildFile(File baseDir) { + return new File(baseDir, subPath); + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/generalutils/LogCounter.groovy b/src/net/sf/jremoterun/utilities/nonjdk/generalutils/LogCounter.groovy new file mode 100644 index 00000000..095b8aab --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/generalutils/LogCounter.groovy @@ -0,0 +1,92 @@ +package net.sf.jremoterun.utilities.nonjdk.generalutils + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class LogCounter { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public volatile int currentCount; + public int countBy; + public int countBy10; + public int countBy100; + public int countBy1000; + public int countBy10000; + public int countBy100000; + public int countBy1000000; + public int countBy10000000; + public int countBy100000000; + + + + LogCounter() { + this(3) + } + + LogCounter(int countBy) { + assert countBy < 10; + this.countBy = countBy + countBy10 = countBy * 10; + countBy100 = countBy * 100; + countBy1000 = countBy * 1000; + countBy10000 = countBy * 10_000; + countBy100000 = countBy * 100_000; + countBy1000000 = countBy * 1_000_000; + countBy10000000 = countBy * 10_000_000; + countBy100000000 = countBy * 100_000_000; + } + + boolean isNeedLog2(int count, int numm) { + if (count % numm == 0) { + return true + } + return false; + + } + + void increaseCount(){ + currentCount++ + } + + boolean isNeedLog3() { + return isNeedLog(currentCount) + } + + boolean isNeedLog(int count) { + if (count < 10) { + return count < countBy; + } + if (count < countBy10) { + return isNeedLog2(count, 10) + } + if (count < countBy100) { + return isNeedLog2(count, 100) + } + if (count < countBy1000) { + return isNeedLog2(count, 1_000) + } + if (count < countBy10000) { + return isNeedLog2(count, 10_000) + } + if (count < countBy100000) { + return isNeedLog2(count, 100_000) + } + + if (count < countBy1000000) { + return isNeedLog2(count, 1_000_000) + } + if (count < countBy10000000) { + return isNeedLog2(count, 10_000_000) + } + if (count < countBy100000000) { + return isNeedLog2(count, 100_000_000) + } + + } + + + public static LogCounter logCounterDefault = new LogCounter() + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/gi2/GitPushHook.groovy b/src/net/sf/jremoterun/utilities/nonjdk/gi2/GitPushHook.groovy index 3f868285..bbc0b551 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/gi2/GitPushHook.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/gi2/GitPushHook.groovy @@ -13,6 +13,8 @@ class GitPushHook extends InjectedCode { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static boolean enabledCheck = true; + public static Collection enabledUrlPushList = []; public static String enabledUrlPush = ""; @@ -26,11 +28,19 @@ class GitPushHook extends InjectedCode { } - void checkImpl(org.eclipse.jgit.transport.Transport transport){ - log.info "checking : ${transport.getURI()}" - URIish uris = transport.getURI(); - if (!uris.toString().startsWith(enabledUrlPush)) { - throw new IllegalStateException("push not allowed for : " + uris); + void checkImpl(org.eclipse.jgit.transport.Transport transport) { + if (enabledCheck) { + log.info "checking : ${transport.getURI()}" + URIish uris = transport.getURI(); + String uriS = uris.toString().toLowerCase() + String foundS = enabledUrlPushList.find { uriS.startsWith(it) } + if(foundS!=null){ + if (!uris.toString().startsWith(enabledUrlPush)) { + throw new IllegalStateException("push not allowed for : " + uris); + } + } + }else{ + log.info "check disabled, pushing ${transport.getURI()}" } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/gi2/GitRepoUpdater.groovy b/src/net/sf/jremoterun/utilities/nonjdk/gi2/GitRepoUpdater.groovy index d333a9b5..0f7c3679 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/gi2/GitRepoUpdater.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/gi2/GitRepoUpdater.groovy @@ -1,18 +1,10 @@ package net.sf.jremoterun.utilities.nonjdk.gi2 -import groovy.transform.CompileStatic; - -import org.eclipse.jgit.api.FetchCommand; -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.errors.NoRemoteRepositoryException; - -import net.sf.jremoterun.JrrUtils; -import net.sf.jremoterun.utilities.JrrClassUtils; - -import java.io.File; -import java.util.List; -import java.util.logging.Logger; +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.git.GitRepoUtils +import java.util.logging.Logger @CompileStatic public class GitRepoUpdater { @@ -22,25 +14,27 @@ public class GitRepoUpdater { static void fetchOneRepo(File repo) throws Exception { log.info("start fetch ${repo}"); - Git git = Git.open(repo); - File file2 = new File(repo,"refs\\remotes"); - File[] listFiles = file2.listFiles(); - for (File file : listFiles) { - try { - log.info("fetching "+file.getAbsolutePath()); - FetchCommand fetchCommand = git.fetch(); - fetchCommand.setRemote(file.getName()); - fetchCommand.call(); - }catch (Exception e) { - Throwable e2 = JrrUtils.getRootException(e); - if (e2 instanceof NoRemoteRepositoryException) { - NoRemoteRepositoryException new_name = (NoRemoteRepositoryException) e2; - log.info(file.getAbsolutePath()+" "+e); - }else { - throw e; - } - } - } + GitRepoUtils gitRepoUtils = new GitRepoUtils(repo) + gitRepoUtils.fetchAllRemote() +// Git git = Git.open(repo); +// File file2 = new File(repo,"refs\\remotes"); +// File[] listFiles = file2.listFiles(); +// for (File file : listFiles) { +// try { +// log.info("fetching "+file.getAbsolutePath()); +// FetchCommand fetchCommand = git.fetch(); +// fetchCommand.setRemote(file.getName()); +// fetchCommand.call(); +// }catch (Exception e) { +// Throwable e2 = JrrUtils.getRootException(e); +// if (e2 instanceof NoRemoteRepositoryException) { +// NoRemoteRepositoryException new_name = (NoRemoteRepositoryException) e2; +// log.info(file.getAbsolutePath()+" "+e); +// }else { +// throw e; +// } +// } +// } } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/git/JrrGitSshFactory.groovy b/src/net/sf/jremoterun/utilities/nonjdk/git/JrrGitSshFactory.groovy new file mode 100644 index 00000000..ac0521a3 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/git/JrrGitSshFactory.groovy @@ -0,0 +1,95 @@ +package net.sf.jremoterun.utilities.nonjdk.git + +import com.jcraft.jsch.JSch +import com.jcraft.jsch.JSchException +import com.jcraft.jsch.Session +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJSch +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschSession +import org.eclipse.jgit.errors.TransportException +import org.eclipse.jgit.transport.CredentialsProvider +import org.eclipse.jgit.transport.JschConfigSessionFactory +import org.eclipse.jgit.transport.JschSession +import org.eclipse.jgit.transport.OpenSshConfig +import org.eclipse.jgit.transport.RemoteSession +import org.eclipse.jgit.transport.SshSessionFactory +import org.eclipse.jgit.transport.URIish +import org.eclipse.jgit.util.FS; + +import java.util.logging.Logger; + +@CompileStatic +class JrrGitSshFactory extends JschConfigSessionFactory { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static volatile boolean useJrrSsh = false + public static volatile boolean inited = false + public static volatile JrrGitSshFactory gitSshFactory; + + static void init() { + if(inited){ + + }else { + inited = true + gitSshFactory = new JrrGitSshFactory(); + JrrClassUtils.setFieldValue(SshSessionFactory, 'INSTANCE', gitSshFactory) + JSch.setConfig("StrictHostKeyChecking", "no"); + } + } + + @Override + protected void configure(OpenSshConfig.Host hc, Session session) { + + } + + + +// @Override +// RemoteSession getSession(URIish uri, CredentialsProvider credentialsProvider, FS fs, int tms) throws TransportException { +// return super.getSession(uri, credentialsProvider, fs, tms) +// } + + @Override + protected JSch getJSch(OpenSshConfig.Host hc, FS fs) throws JSchException { +// log.info "getting jsch .." + return super.getJSch(hc, fs) + } + + @Override + protected Session createSession(OpenSshConfig.Host hc, String user, String host, int port, FS fs) throws JSchException { + log.info "useJrrSsh = ${useJrrSsh}" + if(useJrrSsh) { + JSch jSch = getJSch(hc, fs); + JrrJschSession s = new JrrJschSession(jSch, user, host, port); + return s; + } + return super.createSession(hc,user,host,port,fs); + } + + @Override + RemoteSession getSession(URIish uri, CredentialsProvider credentialsProvider, FS fs, int tms) throws TransportException { + RemoteSession session1 = super.getSession(uri, credentialsProvider, fs, tms) +// if (session instanceof JschSession) { +// JschSession sessionSsh = (JschSession) session; +// return new RemoteSessionGitJrr(sessionSsh.disconnect()) +// } + return session1 + } + + @Override + protected JSch createDefaultJSch(FS fs) throws JSchException { + log.info "getting jsch .." + if(useJrrSsh) { + final JrrJSch jsch = new JrrJSch(); + JSch.setConfig("ssh-rsa", JSch.getConfig("signature.rsa")); //$NON-NLS-1$ //$NON-NLS-2$ + JSch.setConfig("ssh-dss", JSch.getConfig("signature.dss")); //$NON-NLS-1$ //$NON-NLS-2$ + configureJSch(jsch); + JrrClassUtils.invokeJavaMethod(JschConfigSessionFactory, 'knownHosts', jsch, fs); + JrrClassUtils.invokeJavaMethod(JschConfigSessionFactory, 'identities', jsch, fs); + return jsch; + }else { + return super.createDefaultJSch(fs) + } + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/groovy/ExtentionMethodChecker.groovy b/src/net/sf/jremoterun/utilities/nonjdk/groovy/ExtentionMethodChecker.groovy new file mode 100644 index 00000000..cfdc811f --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/groovy/ExtentionMethodChecker.groovy @@ -0,0 +1,36 @@ +package net.sf.jremoterun.utilities.nonjdk.groovy + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.log.FileExtentionClass +import net.sf.jremoterun.utilities.nonjdk.log.JdkLoggerExtentionClass +import org.codehaus.groovy.runtime.m12n.ExtensionModule +import org.codehaus.groovy.runtime.m12n.ExtensionModuleRegistry +import org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule +import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl; + +import java.util.logging.Logger; + +@CompileStatic +class ExtentionMethodChecker { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static void check() { + MetaClassRegistryImpl metaClassRegistry = GroovySystem.getMetaClassRegistry() as MetaClassRegistryImpl; + ExtensionModuleRegistry moduleRegistry = metaClassRegistry.getModuleRegistry(); + MetaInfExtensionModule module = moduleRegistry.getModule('JdkLoggingMethods') as MetaInfExtensionModule + if(module==null){ + throw new Exception('JdkLoggingMethods module not found') + } + List classes = module.getInstanceMethodsExtensionClasses() + if(classes.size()!=2){ + throw new Exception("wrong classes count = ${classes.size()}") + } + if(!classes.contains(JdkLoggerExtentionClass)){ + throw new Exception("${JdkLoggerExtentionClass.getName()} not exist in ${classes}") + } + if(!classes.contains(FileExtentionClass)){ + throw new Exception("${FileExtentionClass.getName()} not exist in ${classes}") + } + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/groovy/ExtentionMethodChecker2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/groovy/ExtentionMethodChecker2.groovy new file mode 100644 index 00000000..009bc4e9 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/groovy/ExtentionMethodChecker2.groovy @@ -0,0 +1,24 @@ +package net.sf.jremoterun.utilities.nonjdk.groovy + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.groovystarter.runners.RunnableFactory +import net.sf.jremoterun.utilities.nonjdk.classpath.helpers.FileChildLazyRef +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GitSomeRefs +import net.sf.jremoterun.utilities.nonjdk.log.FileExtentionClass +import net.sf.jremoterun.utilities.nonjdk.log.JdkLoggerExtentionClass +import org.codehaus.groovy.runtime.m12n.ExtensionModuleRegistry +import org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule +import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl + +import java.util.logging.Logger + +@CompileStatic +class ExtentionMethodChecker2 { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static void check() { + File f = GitSomeRefs.ifFramework.childL('resources/tcpmon/extMethodTester.groovy').resolveToFile(); + RunnableFactory.createRunner(f).run(); + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ivy/IvyDepResolver3.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ivy/IvyDepResolver3.groovy new file mode 100644 index 00000000..5ebcbdbe --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ivy/IvyDepResolver3.groovy @@ -0,0 +1,34 @@ +package net.sf.jremoterun.utilities.nonjdk.ivy + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.mdep.ivy.IBiblioRepository +import net.sf.jremoterun.utilities.mdep.ivy.IvyDepResolver2 +import org.apache.ivy.plugins.resolver.IBiblioResolver; + +import java.util.logging.Logger; + +@CompileStatic +class IvyDepResolver3 extends IvyDepResolver2 { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + IBiblioRepository rrr; + + IvyDepResolver3(IBiblioRepository rrr) { + this.rrr = rrr + } + + @Override + IBiblioResolver buildPublicIbiblio() { + IBiblioResolver iBiblioResolver3 = buildPublicIbiblioCustom(rrr.name(), rrr.url) + failBackDr = iBiblioResolver3 + return iBiblioResolver3 + return super.buildPublicIbiblio() + } + + @Override + String toString() { + return rrr.toString() + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ivy/IvyDownloadFromSpecifiedSource.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ivy/IvyDownloadFromSpecifiedSource.groovy new file mode 100644 index 00000000..575306ad --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ivy/IvyDownloadFromSpecifiedSource.groovy @@ -0,0 +1,24 @@ +package net.sf.jremoterun.utilities.nonjdk.ivy + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.mdep.ivy.IBiblioRepository +import net.sf.jremoterun.utilities.mdep.ivy.IvyDepResolver2 +import net.sf.jremoterun.utilities.mdep.ivy.JrrIvy +import net.sf.jremoterun.utilities.mdep.ivy.JrrIvySettings +import org.apache.ivy.Ivy +import org.apache.ivy.core.report.ResolveReport +import org.apache.ivy.core.settings.IvySettings +import org.apache.ivy.plugins.resolver.IBiblioResolver; + +import java.util.logging.Logger; + +@CompileStatic +class IvyDownloadFromSpecifiedSource { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + //IvyDepResolver2 ivyDepResolver2 + + + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ivy/JrrDependecyAmenderDefault.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ivy/JrrDependecyAmenderDefault.groovy new file mode 100644 index 00000000..599556be --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ivy/JrrDependecyAmenderDefault.groovy @@ -0,0 +1,58 @@ +package net.sf.jremoterun.utilities.nonjdk.ivy + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.mdep.ivy.DependencyResolverDebugger +import net.sf.jremoterun.utilities.mdep.ivy.JrrDependecyAmender +import org.apache.ivy.core.module.descriptor.Artifact +import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor +import org.apache.ivy.core.module.descriptor.DependencyDescriptor +import org.apache.ivy.core.module.descriptor.MDArtifact +import org.apache.ivy.core.module.id.ModuleId +import org.apache.ivy.core.module.id.ModuleRevisionId +import org.apache.ivy.core.resolve.ResolveData +import org.apache.ivy.core.resolve.ResolvedModuleRevision; + +import java.util.logging.Logger; + +@CompileStatic +class JrrDependecyAmenderDefault extends JrrDependecyAmender { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + private static MavenId mavenId1 = new MavenId('javax.ws.rs:javax.ws.rs-api:2.1.1') + + public static void setResolverAmender() { + DependencyResolverDebugger.dependecyAmender = new JrrDependecyAmenderDefault(); + } + + @Override + ResolvedModuleRevision amendIfNeeded(ResolvedModuleRevision resolvedModuleRevision, DependencyDescriptor dd, ResolveData data) { + if(resolvedModuleRevision==null){ + return null + } + ModuleRevisionId moduleRevisionId1 = resolvedModuleRevision.getDescriptor().getModuleRevisionId() + ModuleId moduleId1 = moduleRevisionId1.getModuleId() + if (moduleId1.organisation == mavenId1.groupId && moduleId1.name == mavenId1.artifactId) { + handleJavaWs(resolvedModuleRevision); + } + return resolvedModuleRevision; + } + + + static void handleJavaWs(ResolvedModuleRevision resolvedModuleRevision) { + ModuleRevisionId moduleRevisionId1 = resolvedModuleRevision.getDescriptor().getModuleRevisionId() + ModuleId moduleId1 = moduleRevisionId1.getModuleId() + log.info "inside special handle for module id = ${moduleId1}" + DefaultModuleDescriptor defaultModuleDescriptor1 = resolvedModuleRevision.getDescriptor() as DefaultModuleDescriptor; + Collection artifacts = (Collection) JrrClassUtils.getFieldValue(defaultModuleDescriptor1, 'artifacts') + artifacts.each { + org.apache.ivy.core.module.descriptor.MDArtifact mdArtifact = it as MDArtifact; +// mdArtifact.getId() + if (mdArtifact.getExt() == '${packaging.type}') { + log.info "set jar for ${resolvedModuleRevision.getDescriptor()} by ${resolvedModuleRevision} from ext = ${mdArtifact.getExt()}" + JrrClassUtils.setFieldValue(mdArtifact, 'ext', 'jar'); + } + } + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ivy/JrrIvyURLHandler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ivy/JrrIvyURLHandler.groovy new file mode 100644 index 00000000..a1f97c94 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ivy/JrrIvyURLHandler.groovy @@ -0,0 +1,96 @@ +package net.sf.jremoterun.utilities.nonjdk.ivy + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.ivy.core.settings.TimeoutConstraint + +//import org.apache.ivy.core.settings.TimeoutConstraint +import org.apache.ivy.util.CopyProgressListener +import org.apache.ivy.util.url.BasicURLHandler +import org.apache.ivy.util.url.URLHandler +import org.apache.ivy.util.url.URLHandlerRegistry; + +import java.util.logging.Logger; + + + +@CompileStatic +class JrrIvyURLHandler extends BasicURLHandler { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static URLHandler beforeS; + public URLHandler before2; + + + + static JrrIvyURLHandler setHandlerForce() { + JrrIvyURLHandler handler = new JrrIvyURLHandler() + handler.before2 = URLHandlerRegistry.getDefault() + URLHandlerRegistry.setDefault(handler) + return handler; + } + + + static void setHandler() { + if (beforeS == null) { + JrrIvyURLHandler handler = setHandlerForce() + beforeS = handler.before2 + }else{ + log.info "custom url handler already set : ${beforeS.getClass().getName()}" + } + } + + boolean isNeedLogUrl(URL url){ + if(url.toString().startsWith('jar:file:')){ + return false; + } + if(url.toString().startsWith('file:')){ + return false + } + return true + } + + @Override + URLInfo getURLInfo(URL url, int timeoutConstraint) { + if(isNeedLogUrl(url)) { + log.info "downloading : ${url}" + } + return super.getURLInfo(url, timeoutConstraint) + } + + @Override + void download(URL src, File dest, CopyProgressListener listener, TimeoutConstraint timeoutConstraint) throws IOException { + // this used in ivy 2.5.0 + if(isNeedLogUrl(src)) { + log.info2(src) + } + super.download(src, dest, listener, timeoutConstraint) + } + + @Override + InputStream openStream(URL url) throws IOException { + return super.openStream(url) + } + + @Override + InputStream openStream(URL url, TimeoutConstraint timeoutConstraint) throws IOException { + if(isNeedLogUrl(url)) { + log.info2(url) + } + return super.openStream(url, timeoutConstraint) + } + + @Override + void download(URL src, File dest, CopyProgressListener listener) throws IOException { + if(isNeedLogUrl(src)) { + log.info2(src) + } + super.download(src, dest, listener) + } + + @Override + void upload(File src, URL dest, CopyProgressListener listener) throws IOException { + log.info2(dest) + super.upload(src, dest, listener) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ivy/ManyReposDownloaderImpl.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ivy/ManyReposDownloaderImpl.groovy new file mode 100644 index 00000000..f6cc329d --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ivy/ManyReposDownloaderImpl.groovy @@ -0,0 +1,121 @@ +package net.sf.jremoterun.utilities.nonjdk.ivy + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenDefaultSettings +import net.sf.jremoterun.utilities.classpath.MavenDependenciesResolver +import net.sf.jremoterun.utilities.mdep.ivy.IBiblioRepository +import net.sf.jremoterun.utilities.mdep.ivy.IvyDepResolver2 +import net.sf.jremoterun.utilities.mdep.ivy.JrrIvySettings +import org.apache.ivy.core.event.IvyListener + +import java.util.logging.Logger + + +@CompileStatic +class ManyReposDownloaderImpl extends MavenManyReposDownloader { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public static volatile boolean manyRepoLoaderWasSet = false + public static MavenDependenciesResolver resolverBefore; + + + + public OnRepoCreatedListener repoCreatedListener + MavenDependenciesResolver defaultRepo; + Map repos = [:] + + ManyReposDownloaderImpl(MavenDependenciesResolver defaultRepo) { + this.defaultRepo = defaultRepo + } + + @Override + MavenDependenciesResolver getDefaultRepo() { + return defaultRepo + } + + @Override + MavenDependenciesResolver findRepo(IBiblioRepository repo) { + if (repo == null) { + return defaultRepo; + } + MavenDependenciesResolver resolver = repos.get(repo) + if (resolver == null) { + MavenDependenciesResolver resolver2 = createRepo(repo) + resolver = resolver2 + if(repoCreatedListener!=null){ + repoCreatedListener.onRepoCreated(resolver2 as IvyDepResolver3) + } + repos.put(repo, resolver) + } + return resolver + } + + void addIvyListener(IvyListener ideaIvyEvent){ + + ManyReposDownloaderImpl resolver = this + if(resolver.repoCreatedListener !=null){ + throw new Exception("repoCreatedListener is not null : ${repoCreatedListener}") + } + OnRepoCreatedListener repoCreatedListener = new OnRepoCreatedListener(){ + + @Override + void onRepoCreated(IvyDepResolver3 resolver2) { + resolver2.ivy.eventManager.addIvyListener(ideaIvyEvent); + } + } + resolver.repoCreatedListener = repoCreatedListener + addListener(resolver.defaultRepo,ideaIvyEvent) + resolver.repos.values().toList().each {addListener(it,ideaIvyEvent)} + } + + void removeIvyListener(IvyListener ideaIvyEvent){ + ManyReposDownloaderImpl resolver = this + resolver.repoCreatedListener = null + resolver.repos.values().toList().each {removeListener(it,ideaIvyEvent)} + } + + + private void removeListener(MavenDependenciesResolver r, IvyListener ideaIvyEvent ){ + if (r instanceof IvyDepResolver2) { + IvyDepResolver2 rr= (IvyDepResolver2) r; + rr.ivy.eventManager.removeIvyListener(ideaIvyEvent) + } + } + + private void addListener(MavenDependenciesResolver r,IvyListener ideaIvyEvent ){ + if (r instanceof IvyDepResolver2) { + IvyDepResolver2 rr= (IvyDepResolver2) r; + rr.ivy.eventManager.addIvyListener(ideaIvyEvent) + } + } + + + // force return MavenDependenciesResolver instead of IvyDepResolver3 due to bug when compiling in idea + static MavenDependenciesResolver createRepo(IBiblioRepository rrr) { + IvyDepResolver3 ivyDepResolver2 = new IvyDepResolver3(rrr) + JrrIvySettings ivySettings = ivyDepResolver2.buildSettings(); + ivyDepResolver2.ivy = ivySettings.buildIvy() + return ivyDepResolver2; + } + + + static void setManyRepoLoader() { + if (manyRepoLoaderWasSet) { + log.info "many repo loader already set" + } else { + resolverBefore = MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver + MavenDependenciesResolver resolverBefore2 = resolverBefore; + if (resolverBefore2 == null) { + net.sf.jremoterun.utilities.mdep.ivy.IvyDepResolver2.setDepResolverImpl() + } + resolverBefore2 = MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver + assert resolverBefore2 != null + MavenDefaultSettings.mavenDefaultSettings.mavenDependenciesResolver = new ManyReposDownloaderImpl(resolverBefore2) + log.info "many resolver was set" + } + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ivy/MavenManyReposDownloader.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ivy/MavenManyReposDownloader.groovy new file mode 100644 index 00000000..09a26977 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ivy/MavenManyReposDownloader.groovy @@ -0,0 +1,71 @@ +package net.sf.jremoterun.utilities.nonjdk.ivy + +import groovy.transform.CompileStatic +import net.sf.jremoterun.JrrUtils +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.MavenDependenciesResolver +import net.sf.jremoterun.utilities.classpath.MavenId +import net.sf.jremoterun.utilities.classpath.MavenPath +import net.sf.jremoterun.utilities.mdep.ivy.IBiblioRepository + +import java.util.logging.Logger + +@CompileStatic +abstract class MavenManyReposDownloader implements MavenDependenciesResolver { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + abstract MavenDependenciesResolver getDefaultRepo(); + abstract MavenDependenciesResolver findRepo(IBiblioRepository repo); + + + @Override + List resolveAndDownloadDeepDependencies(MavenId mavenId, boolean downloadSource, boolean dep, IBiblioRepository repo) { + MavenDependenciesResolver repo1 = findRepo(repo) + return repo1.resolveAndDownloadDeepDependencies(mavenId,downloadSource,dep); + } + + @Override + void downloadSource(MavenId mavenId, IBiblioRepository repo) { + MavenDependenciesResolver repo1 = findRepo(repo) + repo1.downloadSource(mavenId) + } + + @Override + void downloadMavenPath(MavenPath path, boolean dep) { + downloadMavenPath(path,dep); + } + + @Override + void downloadPathImplSpecific(String path, boolean dep) { + downloadPathImplSpecific(path,dep); + } + + + @Override + List resolveAndDownloadDeepDependencies(MavenId mavenId, boolean downloadSource, boolean dep) { + return getDefaultRepo().resolveAndDownloadDeepDependencies(mavenId,downloadSource,dep); + } + + @Override + void downloadSource(MavenId mavenId) { + getDefaultRepo().downloadSource(mavenId); + } + + + + @Override + File getMavenLocalDir() { + return getDefaultRepo().getMavenLocalDir() + } + + @Override + URL getMavenRepoUrl() { + return getDefaultRepo().getMavenRepoUrl() + } + + + + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ivy/OnRepoCreatedListener.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ivy/OnRepoCreatedListener.groovy new file mode 100644 index 00000000..2ddf16f4 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ivy/OnRepoCreatedListener.groovy @@ -0,0 +1,13 @@ +package net.sf.jremoterun.utilities.nonjdk.ivy + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +interface OnRepoCreatedListener { + + void onRepoCreated(IvyDepResolver3 resolver2); + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/javassist/ClassRedefinitionTester.groovy b/src/net/sf/jremoterun/utilities/nonjdk/javassist/ClassRedefinitionTester.groovy index 3a5a4a12..cc1ccb7b 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/javassist/ClassRedefinitionTester.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/javassist/ClassRedefinitionTester.groovy @@ -8,14 +8,14 @@ import groovy.transform.CompileStatic; @CompileStatic -class ClassRedefinitionTester implements Runnable{ +class ClassRedefinitionTester implements Runnable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); @Test @Override void run() { - ClassRedefintions.redefineSunReflection() + ClassRedefintions.redefineSunReflectionIfCan() ClassRedefintions.redifineAccessibleObject() ClassRedefintions.redefineX509TrustManagerImpl() ClassRedefintions.redifinePackage() @@ -25,6 +25,7 @@ class ClassRedefinitionTester implements Runnable{ ClassRedefintions.redifineHttpsCertificateCheck1() ClassRedefintions.redifineClassLoader() ClassRedefintions.redefindeDnsResolving() + ClassRedefintions.redefineSystemExit(true) LoggigingRedefine.redifineCommonsLoggingGetLog() // LoggigingRedefine.redifineSl4jLoggingGetLog() diff --git a/src/net/sf/jremoterun/utilities/nonjdk/javassist/ClassRedefintions.groovy b/src/net/sf/jremoterun/utilities/nonjdk/javassist/ClassRedefintions.groovy index 23d37198..bdbdcf35 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/javassist/ClassRedefintions.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/javassist/ClassRedefintions.groovy @@ -1,5 +1,6 @@ package net.sf.jremoterun.utilities.nonjdk.javassist +import com.google.common.reflect.Types import groovy.transform.CompileStatic import javassist.ClassClassPath import javassist.ClassPath @@ -12,6 +13,8 @@ import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.JrrUtilities import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.javassist.JrrJavassistUtils +import org.apache.commons.lang3.JavaVersion +import org.apache.commons.lang3.SystemUtils import java.util.logging.Logger @@ -19,6 +22,7 @@ import static net.sf.jremoterun.utilities.javassist.JrrJavassistUtils.LogVarName import static net.sf.jremoterun.utilities.javassist.JrrJavassistUtils.createLogVar import static net.sf.jremoterun.utilities.javassist.JrrJavassistUtils.findMethod import static net.sf.jremoterun.utilities.javassist.JrrJavassistUtils.getClassFromDefaultPool +import static net.sf.jremoterun.utilities.javassist.JrrJavassistUtils.mapVarName import static net.sf.jremoterun.utilities.javassist.JrrJavassistUtils.redefineClass @CompileStatic @@ -46,8 +50,12 @@ public class ClassRedefintions { Class clazz = java.lang.Package final CtClass cc = JrrJavassistUtils.getClassFromDefaultPool(clazz); if (true) { - CtBehavior method1 = JrrJavassistUtils.findMethod(clazz, cc, "isSealed", 1); - method1.setBody("{return false;}"); + try { + CtBehavior method1 = JrrJavassistUtils.findMethod(clazz, cc, "isSealed", 1); + method1.setBody("{return false;}"); + }catch(NoSuchMethodException e){ + log.info( "failed find isSealed method with 1 param ",e) + } } if (true) { CtBehavior method1 = JrrJavassistUtils.findMethod(clazz, cc, "isSealed", 0); @@ -56,6 +64,19 @@ public class ClassRedefintions { JrrJavassistUtils.redefineClass(cc, clazz); } + static void redefineSystemExit(boolean append) throws Exception { + init(); + Class clazz = Runtime + final CtClass cc = JrrJavassistUtils.getClassFromDefaultPool(clazz); + CtBehavior method1 = JrrJavassistUtils.findMethod(clazz, cc, "exit", 1); + if(append){ + method1.insertBefore("{Thread.dumpStack();}"); + }else { + method1.setBody("{Thread.dumpStack();}"); + } + JrrJavassistUtils.redefineClass(cc, clazz); + } + static void redifineUrlClassLoader() throws Exception { init(); Class clazz = URLClassLoader @@ -77,6 +98,18 @@ public class ClassRedefintions { JrrJavassistUtils.redefineClass(cc, clazz); } + /** + TODO works ? + */ + static void redefineClassloaderCertCheck() throws Exception { + init(); + Class clazz = ClassLoader + final CtClass cc = JrrJavassistUtils.getClassFromDefaultPool(clazz); + CtBehavior method1 = JrrJavassistUtils.findMethod(clazz, cc, "checkCerts", 2); + method1.setBody("{}"); + JrrJavassistUtils.redefineClass(cc, clazz); + } + static void redifineAccessibleObject() throws Exception { init(); Class clazz = java.lang.reflect.AccessibleObject @@ -105,22 +138,83 @@ public class ClassRedefintions { JrrJavassistUtils.redefineClass(cc, clazz); } + static void redefineServiceLoader(String JrrServiceLoaderFactoryS) throws Exception { + init(); + Class clazz = ServiceLoader + final CtClass cc = getClassFromDefaultPool(clazz); + CtBehavior iteratorMethod = JrrJavassistUtils.findMethod(clazz, cc, 'iterator', 0) + iteratorMethod.insertBefore """ +{ +${JrrJavassistUtils.createGlobalServicesMapVar} +java.util.Map jrrServiceLoaderFactory = (java.util.Map) ${mapVarName}.get( "${JrrServiceLoaderFactoryS}" ); +java.util.Iterator jrrresult = (java.util.Iterator)jrrServiceLoaderFactory.get(this); +if(jrrresult!=null){ + return jrrresult; +} +} +""" + JrrJavassistUtils.redefineClass(cc, clazz); + } + static void redifineHttpsCertificateCheck1() throws Exception { init(); ClRef cr = new ClRef('sun.net.www.protocol.https.HttpsClient') - Class class1 = cr.loadClass(JrrUtilities.getCurrentClassLoader()); + Class class1 = cr.loadClass(JrrClassUtils.getCurrentClassLoader()); final CtClass cc = getClassFromDefaultPool(class1); final CtMethod method = cc.getDeclaredMethod("checkURLSpoofing"); method.setBody("{}"); JrrJavassistUtils.redefineClass(cc, class1); } + static void redefineSslHandshakerIfCan() throws Exception { + boolean isJava9Plus = SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9) + if(isJava9Plus){ + + }else { + redefineSslHandshaker() + } + } + + /** + * Not works on java9+ + */ + static void redefineSslHandshaker() throws Exception { + init(); + ClRef cr = new ClRef('sun.security.ssl.Handshaker') + Class class1 = cr.loadClass(JrrClassUtils.getCurrentClassLoader()); + final CtClass cc = getClassFromDefaultPool(class1); + final CtMethod method = JrrJavassistUtils.findMethod(cc,'fatalSE',3) + method.setBody("{}"); + JrrJavassistUtils.redefineClass(cc, class1); + } + + + static void redefineJava11BuiltinClassLoaderIfCan() throws Exception { + boolean isJava9Plus = SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9) + if(isJava9Plus){ + redefineJava11BuiltinClassLoader() + }else { + + } + } + + static void redefineJava11BuiltinClassLoader() throws Exception { + init(); + ClRef cr = new ClRef('jdk.internal.loader.BuiltinClassLoader') + Class class1 = cr.loadClass(JrrClassUtils.getCurrentClassLoader()); + + final CtClass cc = getClassFromDefaultPool(class1); + final CtBehavior isSealedMethod = findMethod(class1, cc, "isSealed", 2); + + isSealedMethod.setBody("{return false;}") ; + JrrJavassistUtils.redefineClass(cc, class1); + } static void redefineX509TrustManagerImpl() throws Exception { init(); ClRef cr = new ClRef('sun.security.ssl.X509TrustManagerImpl') - Class class1 = cr.loadClass(JrrUtilities.getCurrentClassLoader()); + Class class1 = cr.loadClass(JrrClassUtils.getCurrentClassLoader()); final CtClass cc = getClassFromDefaultPool(class1); final Collection methods = cc.getDeclaredMethods().findAll { it.name == 'checkTrusted' }; @@ -129,10 +223,19 @@ public class ClassRedefintions { JrrJavassistUtils.redefineClass(cc, class1); } + static void redefineSunReflectionIfCan() throws Exception { + boolean isJava9Plus = SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9) + if(isJava9Plus){ + + }else { + redefineSunReflection() + } + } + static void redefineSunReflection() throws Exception { init(); ClRef cr = new ClRef('sun.reflect.Reflection') - Class class1 = sun.reflect.Reflection;//cr.loadClass(JrrUtilities.getCurrentClassLoader()); + Class class1 = cr.loadClass2();//cr.loadClass(JrrUtilities.getCurrentClassLoader()); final CtClass cc = getClassFromDefaultPool(class1); final CtMethod method1 = JrrJavassistUtils.findMethod(class1,cc,'ensureMemberAccess',4) diff --git a/src/net/sf/jremoterun/utilities/nonjdk/javassist/ExprEditorPrintStackTrace.groovy b/src/net/sf/jremoterun/utilities/nonjdk/javassist/ExprEditorPrintStackTrace.groovy new file mode 100644 index 00000000..4ec083e9 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/javassist/ExprEditorPrintStackTrace.groovy @@ -0,0 +1,23 @@ +package net.sf.jremoterun.utilities.nonjdk.javassist + +import groovy.transform.CompileStatic +import javassist.CannotCompileException +import javassist.expr.ExprEditor +import javassist.expr.Handler; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +/** + * Usage : + * CtMethod.instrument(new ExprEditorPrintStackTrace()) + */ +@CompileStatic +class ExprEditorPrintStackTrace extends ExprEditor{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void edit(Handler h) throws CannotCompileException { + h.insertBefore '$1.printStackTrace();' + super.edit(h) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/javassist/LoggigingRedefine.groovy b/src/net/sf/jremoterun/utilities/nonjdk/javassist/LoggigingRedefine.groovy index a59c82bf..fe8ea442 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/javassist/LoggigingRedefine.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/javassist/LoggigingRedefine.groovy @@ -4,8 +4,10 @@ import groovy.transform.CompileStatic import javassist.CtClass import javassist.CtMethod import net.sf.jremoterun.JrrUtils +import net.sf.jremoterun.SimpleJvmTiAgent import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.javassist.JrrJavassistUtils +import net.sf.jremoterun.utilities.nonjdk.classpath.inittracker.InitLogTracker import net.sf.jremoterun.utilities.nonjdk.log.JavaCommonsLogger import net.sf.jremoterun.utilities.nonjdk.log.Sl4jLogger import org.apache.commons.logging.LogFactory @@ -22,6 +24,8 @@ class LoggigingRedefine { private static volatile boolean initDone = false; + public static volatile boolean commonsLoggingRedefined = false + public static volatile boolean sl4jLoggingRedefined = false static void init() throws Exception { if (!initDone) { @@ -35,16 +39,22 @@ class LoggigingRedefine { try { init(); } catch (Exception e1) { - log.log(Level.WARNING, "", e1); + InitLogTracker.defaultTracker.addException("failed redefine logging", e1); + log.log(Level.WARNING, "failed redefine logging", e1); return; } + URL location1 = JrrUtils.getClassLocation(LogFactory) try { URL location = location1 log.info "commons log location ${location}" - redifineCommonsLoggingGetLog(); + if (SimpleJvmTiAgent.instrumentation != null) { + redifineCommonsLoggingGetLog(); + commonsLoggingRedefined = true + } } catch (Throwable e) { log.log(Level.WARNING, "failed redine commons LogFactory from ${location1}", e); + InitLogTracker.defaultTracker.addException("failed redine commons LogFactory from ${location1}", e); } URL location = JrrUtils.getClassLocation(StaticLoggerBinder) log.info "sl4j log location ${location}" @@ -52,9 +62,13 @@ class LoggigingRedefine { log.info "failed redefine sl4j logger : used logback ${location}" } else { try { - redifineSl4jLoggingGetLog(); + if (SimpleJvmTiAgent.instrumentation != null) { + redifineSl4jLoggingGetLog(); + sl4jLoggingRedefined = true + } } catch (Throwable e) { log.log(Level.WARNING, "failed redefine sl4j StaticLoggerBinder from ${location}", e); + InitLogTracker.defaultTracker.addException("failed redefine sl4j StaticLoggerBinder from ${location}", e); } } } @@ -78,7 +92,7 @@ class LoggigingRedefine { final CtClass cc = JrrJavassistUtils.getClassFromDefaultPool(class1); final CtMethod method = JrrJavassistUtils.findMethod(class1, cc, "getILoggerFactory", 0); method.setBody """ - return ${org.slf4j.impl.StaticLoggerBinder.name}.getSingleton().getLoggerFactory(); + return ${org.slf4j.impl.StaticLoggerBinder.getName()}.getSingleton().getLoggerFactory(); """; JrrJavassistUtils.redefineClass(cc, class1); diff --git a/src/net/sf/jremoterun/utilities/nonjdk/jmx/MbeanConnectionCreatorCache.groovy b/src/net/sf/jremoterun/utilities/nonjdk/jmx/MbeanConnectionCreatorCache.groovy new file mode 100644 index 00000000..2efc4e55 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/jmx/MbeanConnectionCreatorCache.groovy @@ -0,0 +1,60 @@ +package net.sf.jremoterun.utilities.nonjdk.jmx + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.MBeanClient +import net.sf.jremoterun.utilities.MbeanConnectionCreator + +import javax.management.ObjectName; +import java.util.logging.Logger; + +@CompileStatic +class MbeanConnectionCreatorCache { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static Object lock = new Object() + public static Map port2connectoin = [:]; + public static Map class2connection = [:]; + + static T getClient(Class clazz, String host, int port, ObjectName objectName) { + String key = clazz.getName() + ':' + host + ':' + port+':'+objectName; + Object obj = class2connection.get(key) + if (obj == null) { + synchronized (lock) { + obj = port2connectoin.get(key) + if (obj == null) { + MbeanConnectionCreator connection = getConnection(host, port) + obj = MBeanClient.buildMbeanClient(clazz, connection, objectName); + if (!clazz.isInstance(obj)) { + throw new ClassCastException("Failed cast ${obj.getClass()} to ${clazz.getName()}") + } + class2connection.put(key, obj) as T + } + } + } + if (!clazz.isInstance(obj)) { + throw new ClassCastException("Failed cast ${obj.getClass()} to ${clazz.getName()}") + } + return obj as T + } + + static MbeanConnectionCreator getConnection(String host, int port) { + String key = host + ':' + port + MbeanConnectionCreator get1 = port2connectoin.get(key) + if (get1 == null) { + synchronized (lock) { + get1 = port2connectoin.get(key) + if (get1 == null) { + get1 = new MbeanConnectionCreator(key); + port2connectoin.put(key, get1) + } + } + } + return get1; + } + + static MbeanConnectionCreator getLocalConnection(int port) { + return getConnection('127.0.0.1', port); + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/langimprovetesters/FieldAccessTester.groovy b/src/net/sf/jremoterun/utilities/nonjdk/langimprovetesters/FieldAccessTester.groovy index d55e9385..fa37e1a8 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/langimprovetesters/FieldAccessTester.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/langimprovetesters/FieldAccessTester.groovy @@ -18,8 +18,8 @@ class FieldAccessTester extends Script { static void fieldAccess() { URLClassLoader cl = new URLClassLoader(new URL[0], ExtMethodsTester.classLoader) - Object pdcache = cl.@pdcache - pdcache.toString() +// Object pdcache = cl.@pdcache +// pdcache.toString() } static void smartCast() { diff --git a/src/net/sf/jremoterun/utilities/nonjdk/langutils/LangUtils.groovy b/src/net/sf/jremoterun/utilities/nonjdk/langutils/LangUtils.groovy deleted file mode 100644 index 947fcc86..00000000 --- a/src/net/sf/jremoterun/utilities/nonjdk/langutils/LangUtils.groovy +++ /dev/null @@ -1,55 +0,0 @@ -package net.sf.jremoterun.utilities.nonjdk.langutils - -import groovy.transform.CompileStatic; -import net.sf.jremoterun.utilities.JrrClassUtils; -import java.util.logging.Logger; - -@CompileStatic -class LangUtils { - private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - - String[] getLibPathSystem(){ - String[] res = JrrClassUtils.getFieldValue(ClassLoader,'sys_paths') as String[]; - return res - } - - String[] getLibPathUser(){ - String[] res = JrrClassUtils.getFieldValue(ClassLoader,'usr_paths') as String[]; - if(res==null){ - log.info "lib not loaded" - } - return res - } - - void setLibToUserPathUnsafe(List path2){ - String[] array = path2.toArray(new String[0]) - JrrClassUtils.setFieldValue(ClassLoader,'usr_paths',array) - } - - void addLibToUserPath(File path2){ - assert path2.isDirectory() - List list = getLibPathUser().toList() - list.add(path2.absolutePath) - setLibToUserPathUnsafe(list) - } - - void insertLibToUserPath(File path2){ - assert path2.isDirectory() - List list = getLibPathUser().toList() - list.add(0,path2.absolutePath) - setLibToUserPathUnsafe(list) - - } - - // java.lang.ClassLoader.NativeLibrary is element - Vector getSystemNativeLibraries(){ - Vector res = JrrClassUtils.getFieldValue(ClassLoader,'systemNativeLibraries') as Vector; - return res - } - - Vector getSystemNativeLoadedLibraries(){ - Vector res = JrrClassUtils.getFieldValue(ClassLoader,'loadedLibraryNames') as Vector; - return res - } - -} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/AddDefaultIgnoreClasses.groovy b/src/net/sf/jremoterun/utilities/nonjdk/log/AddDefaultIgnoreClasses.groovy new file mode 100644 index 00000000..7b633ca9 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/AddDefaultIgnoreClasses.groovy @@ -0,0 +1,99 @@ +package net.sf.jremoterun.utilities.nonjdk.log + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import org.apache.ivy.util.AbstractMessageLogger +import org.apache.ivy.util.DefaultMessageLogger +import org.apache.ivy.util.MessageLoggerEngine; + +import java.util.logging.Logger; + +@CompileStatic +class AddDefaultIgnoreClasses implements Runnable{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void run() { + addIgnoreClasses(); + } + + static void addAzureIgnoreClasses(){ + JrrClassUtils.ignoreClassesForCurrentClass.add('com.azure.core.util.logging.'); + JrrClassUtils.ignoreClassesForCurrentClass.add('com.microsoft.rest.interceptors.'); + addClRef(new ClRef('com.microsoft.rest.interceptors.LoggingInterceptor')); + addClRef(new ClRef('com.microsoft.rest.retry.RetryHandler')); + addClRef(new ClRef('com.microsoft.azure.credentials.AzureTokenCredentialsInterceptor')); + addClRef(new ClRef('com.microsoft.azure.management.resources.fluentcore.utils.ResourceManagerThrottlingInterceptor')); + addClRef(new ClRef('com.microsoft.azure.management.resources.fluentcore.utils.ProviderRegistrationInterceptor')); + + } + + static void addOkHttpIgnoreClasses(){ + addClRef(new ClRef('okhttp3.internal.http.RealInterceptorChain')); + addClRef(new ClRef('okhttp3.internal.connection.ConnectInterceptor')); + addClRef(new ClRef('okhttp3.internal.cache.CacheInterceptor')); + addClRef(new ClRef('okhttp3.internal.http.BridgeInterceptor')); + addClRef(new ClRef('okhttp3.internal.http.RetryAndFollowUpInterceptor')); + addClRef(new ClRef('okhttp3.internal.connection.RealCall')); + + } + + static void addRetrofit(){ + addClRef(new ClRef('retrofit2.OkHttpCall')); + addClRef(new ClRef('retrofit2.adapter.rxjava.CallExecuteOnSubscribe')); + addClRef(new ClRef('rx.Observable')); + addClRef(new ClRef('rx.internal.operators.OnSubscribeMap')); + addClRef(new ClRef('rx.internal.operators.OnSubscribeLift')); + addClRef(new ClRef('rx.observables.BlockingObservable')); + } + + static void addIgnoreClasses(){ + addClRef(new ClRef('org.jetbrains.java.decompiler.IdeaLogger')); + addClRef(new ClRef('reactor.util.Loggers')); + addClRef(new ClRef('org.netbeans.lib.profiler.ProfilerLogger')); + addClRef(new ClRef('net.sf.jremoterun.utilities.nonjdk.idwutils.alerttable.AlertTableWrapper')); + addClRef(new ClRef('com.jcraft.jsch.JrrSchSessionLog')); + addClRef(new ClRef('org.eclipse.core.internal.runtime.PlatformLogWriter')); + addClRef(new ClRef('org.jboss.windup.decompiler.fernflower.FernflowerJDKLogger')); + addClRef(new ClRef("org.apache.kafka.common.utils.LogContext")); + addClRef(new ClRef("sun.net.www.protocol.http.HttpURLConnection")); + addClRef(new ClRef("sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection")); + addClRef(new ClRef("java.net.SocksSocketImpl")); + addClRef(new ClRef("org.sonatype.guice.bean.reflect.Logs")); + addClRef(new ClRef("org.glassfish.jersey.logging.LoggingInterceptor")); + addClRef(new ClRef("net.sf.jremoterun.utilities.nonjdk.git.GitProgressMonitorJrr")); + + JrrClassUtils.ignoreClassesForCurrentClass.add("org.apache.maven.cli.logging"); + JrrClassUtils.ignoreClassesForCurrentClass.add("org.apache.maven.monitor.logging"); + JrrClassUtils.ignoreClassesForCurrentClass.add("org.eclipse.jdt.internal.junit"); + JrrClassUtils.ignoreClassesForCurrentClass.add("org.eclipse.osgi.internal.log."); + JrrClassUtils.ignoreClassesForCurrentClass.add("org.eclipse.core.internal.runtime.Log."); + JrrClassUtils.ignoreClassesForCurrentClass.add('io.netty.util.internal.logging.'); +// JrrClassUtils.ignoreClassesForCurrentClass.add(Log4j2Utils.class.getPackage().getName()); + JrrClassUtils.ignoreClassesForCurrentClass.add(Log4j1Utils.getPackage().getName()); + addClRef(org.eclipse.jgit.lib.BatchingProgressMonitor); + addClRef(org.eclipse.jgit.lib.ThreadSafeProgressMonitor); + addClRef(net.sf.jremoterun.utilities.nonjdk.ivy.JrrIvyURLHandler); + addClRef(net.sf.jremoterun.utilities.nonjdk.log.JdkIntoLog4j2Converter); + addClRef(net.sf.jremoterun.utilities.mdep.ivy.JrrIvyMessageLogger); + addClRef(org.apache.ivy.util.DefaultMessageLogger); + addClRef(org.apache.ivy.util.AbstractMessageLogger); + addClRef(org.apache.ivy.util.MessageLoggerEngine); + addClRef(org.apache.ivy.util.Message); + addOkHttpIgnoreClasses() + //added for azure http headers logs + addAzureIgnoreClasses() + addRetrofit() + } + + + static void addClRef(Class clRef){ + JrrClassUtils.ignoreClassesForCurrentClass.add(clRef.getName()); + } + + static void addClRef(ClRef clRef){ + JrrClassUtils.ignoreClassesForCurrentClass.add(clRef.className); + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/JavaCommonsLogger.groovy b/src/net/sf/jremoterun/utilities/nonjdk/log/JavaCommonsLogger.groovy index 6794bdfd..74507d28 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/log/JavaCommonsLogger.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/JavaCommonsLogger.groovy @@ -10,12 +10,17 @@ import org.apache.commons.logging.impl.LogFactoryImpl public class JavaCommonsLogger { - public + static void setCommonsLoggerToLog4j2() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { LogFactory.releaseAll(); org.apache.logging.log4j.jcl.LogFactoryImpl log4jLoggerLogFactory = new org.apache.logging.log4j.jcl.LogFactoryImpl(); - Log instance = log4jLoggerLogFactory.getInstance("test"); - JrrClassUtils.setFieldValue(LogFactory.class, "nullClassLoaderFactory", log4jLoggerLogFactory); + setCommonsLoggerTo(log4jLoggerLogFactory) + } + + static void setCommonsLoggerTo(LogFactory logFactory) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + LogFactory.releaseAll(); + Log instance = logFactory.getInstance("test"); + JrrClassUtils.setFieldValue(LogFactory, "nullClassLoaderFactory", logFactory); } static setLoggerProps() { diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/JdkLog2Log4jInit.java b/src/net/sf/jremoterun/utilities/nonjdk/log/JdkLog2Log4jInit.java index 5ac1ee63..6dde0740 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/log/JdkLog2Log4jInit.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/JdkLog2Log4jInit.java @@ -1,6 +1,7 @@ package net.sf.jremoterun.utilities.nonjdk.log; import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.nonjdk.classpath.inittracker.InitLogTracker; import org.fusesource.jansi.AnsiConsole; import java.util.logging.Handler; @@ -8,12 +9,26 @@ public class JdkLog2Log4jInit { private static boolean inited = false; + public static boolean printMsgOnError = true; public static void jdk2log4j() { + try{ + jdk2log4jImpl(); + }catch (Throwable e){ + if(printMsgOnError) { + System.err.println("Failed configure log4j2 : "+e); + e.printStackTrace(); + } + InitLogTracker.defaultTracker.addException("failed set appender for jdk logger",e); + throw e; + } + } + public static void jdk2log4jImpl() { if (inited) { return; } - JrrClassUtils.ignoreClassesForCurrentClass.add(Log4j2Utils.class.getPackage().getName()); + + AddDefaultIgnoreClasses.addIgnoreClasses(); // org.apache.logging.log4j.jul.DefaultLevelConverter JdkIntoLog4j2Converter logHandler = new JdkIntoLog4j2Converter(); diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j1Utils.java b/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j1Utils.java index 64c05c6c..de341e94 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j1Utils.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j1Utils.java @@ -4,6 +4,7 @@ import net.sf.jremoterun.utilities.JavaVMClient; import net.sf.jremoterun.utilities.JrrClassUtils; import net.sf.jremoterun.utilities.log4j.Log4jConfigurator; +import net.sf.jremoterun.utilities.nonjdk.classpath.inittracker.InitLogTracker; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Level; import org.apache.log4j.LogManager; @@ -19,44 +20,60 @@ public class Log4j1Utils { public static String sep = "\n"; + public static boolean printMsgOnError = true; + public static Level logRootLevel = Level.INFO; public static Log4j1PatternLayout pl = new Log4j1PatternLayout(); public static void setLog4jAppender() throws Exception { - JrrClassUtils.ignoreClassesForCurrentClass.add(Log4j2Utils.class.getPackage().getName()); - if(true) { - Log4jMigrateUtils.setLog4jAppender(); - return; - } - LogManager.resetConfiguration(); - - final MBeanServer beanServer = JrrUtils.findLocalMBeanServer(); - for (final ObjectName objectName : beanServer.queryNames(Log4jConfigurator.queryLog4jObjectName, null)) { - if (!objectName.equals(JavaVMClient.log4jHierarchyObjectName) - && !objectName.equals(Log4jConfigurator.loggerLoggerObjectName) - && !objectName.equals(JavaVMClient.log4jHierarchyObjectName)) { - try { - beanServer.unregisterMBean(objectName); - } catch (Exception e) { - e.printStackTrace(); - } + try{ + setLog4jAppenderImpl(); + }catch (Throwable e){ + if(printMsgOnError) { + System.err.println("Failed configure log4j2 : "+e); + e.printStackTrace(); } + InitLogTracker.defaultTracker.addException("failed set appender for log4j1",e); + throw e; } - org.apache.log4j.ConsoleAppender ca = new ConsoleAppender(pl); - ca.setName("IfMain"); - org.apache.log4j.Logger.getRootLogger().addAppender(ca); - org.apache.log4j.Logger.getRootLogger().setLevel(logRootLevel); - try { - Log4jConfigurator.registerLog4jLoggersMBeansUsingCreateMethods(); - } catch (Exception e) { - Throwable rootException = JrrUtils.getRootException(e); - if (rootException instanceof ClassNotFoundException) { - ClassNotFoundException cnfe = (ClassNotFoundException) rootException; - log.info(cnfe + ""); - } + } - } + public static void setLog4jAppenderImpl() throws Exception { + JrrClassUtils.ignoreClassesForCurrentClass.add(Log4j2Utils.class.getPackage().getName()); +// if(true) { + Log4jMigrateUtils.setLog4jAppender(); +// return; +// } +// LogManager.resetConfiguration(); +// +// final MBeanServer beanServer = JrrUtils.findLocalMBeanServer(); +// for (final ObjectName objectName : beanServer.queryNames(Log4jConfigurator.queryLog4jObjectName, null)) { +// if (!objectName.equals(JavaVMClient.log4jHierarchyObjectName) +// && !objectName.equals(Log4jConfigurator.loggerLoggerObjectName) +// && !objectName.equals(JavaVMClient.log4jHierarchyObjectName)) { +// try { +// beanServer.unregisterMBean(objectName); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// org.apache.log4j.ConsoleAppender ca = new ConsoleAppender(pl); +// ca.setName("IfMain"); +// org.apache.log4j.Logger.getRootLogger().addAppender(ca); +// org.apache.log4j.Logger.getRootLogger().setLevel(logRootLevel); +// try { +// Log4jConfigurator.registerLog4jLoggersMBeansUsingCreateMethods(); +// } catch (Exception e) { +// InitLogTracker.defaultTracker.addException("failed set appender for log4j1",e); +// Throwable rootException = JrrUtils.getRootException(e); +// if (rootException instanceof ClassNotFoundException) { +// ClassNotFoundException cnfe = (ClassNotFoundException) rootException; +// log.info(cnfe + ""); +// } +// +// } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j2PatternLayout.java b/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j2PatternLayout.java index 0b879fa5..10b3ce7a 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j2PatternLayout.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j2PatternLayout.java @@ -7,7 +7,6 @@ import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.layout.ByteBufferDestination; import org.apache.logging.log4j.message.Message; -import org.apache.logging.log4j.util.StringBuilderFormattable; import java.io.PrintWriter; import java.io.StringWriter; @@ -136,16 +135,16 @@ public void formatImpl2(LogEvent logRecord, StringBuilder sb, StackTraceElement[ // if(s.contains("http://search.maven.org/#search")){ // Thread.dumpStack(); // } - logMessage(sb,s,logRecord); + logMessage(sb, s, logRecord); } } - logStackTrace(logRecord, sb, stackTraces, location); + logStackTraceIfNeeded(logRecord, sb, stackTraces, location); sb.append(sep); } - public void logMessage(StringBuilder sb, String msg,LogEvent logRecord){ + public void logMessage(StringBuilder sb, String msg, LogEvent logRecord) { sb.append(msg); } @@ -206,43 +205,59 @@ public void logTime(LogEvent logRecord, StringBuilder sb) { } } - public void logStackTrace(LogEvent logRecord, StringBuilder sb, StackTraceElement[] stackTraces, StackTraceElement location) { - boolean error = false; - if (Level.WARN.isLessSpecificThan(logRecord.getLevel())) { - error = true; + public void onEmptyStackTrace(LogEvent logRecord, StringBuilder sb, StackTraceElement[] stackTraces, StackTraceElement location, Throwable ti) { + + } + + + public boolean isNeedPrintStackTrace(LogEvent logRecord, StringBuilder sb, StackTraceElement[] stackTraces, StackTraceElement location, Throwable ti) { + if (!Level.WARN.isLessSpecificThan(logRecord.getLevel())) { + return false; } + boolean isLogStackTrace = isLogExceptionStackTrace.isLogStackTrace(logRecord, sb, stackTraces, location, ti); + return isLogStackTrace; + } + + public void logStackTraceIfNeeded(LogEvent logRecord, StringBuilder sb, StackTraceElement[] stackTraces, StackTraceElement location) { Throwable ti = logRecord.getThrown(); - if (ti != null) { - sb.append(" "); - Throwable rootException = JrrUtils.getRootException(ti); + final boolean error = isNeedPrintStackTrace(logRecord, sb, stackTraces, location, ti); + if (ti == null) { if (error) { - boolean isLogStackTrace = isLogExceptionStackTrace.isLogStackTrace(logRecord, sb, stackTraces, location, ti); - error = isLogStackTrace; + writeStackTrace(sb, stackTraces); } + } else { + sb.append(" "); + Throwable rootException = JrrUtils.getRootException(ti); if (error) { - final StringWriter stringWriter = new StringWriter(); - rootException.printStackTrace(new PrintWriter(stringWriter)); - sb.append(stringWriter.getBuffer()); + StackTraceElement[] stackTraces3 = rootException.getStackTrace(); + if (stackTraces3 == null || stackTraces3.length == 0) { + onEmptyStackTrace(logRecord, sb, stackTraces, location, ti); + writeStackTrace(sb, stackTraces); + } else { + final StringWriter stringWriter = new StringWriter(); + rootException.printStackTrace(new PrintWriter(stringWriter)); + sb.append(stringWriter.getBuffer()); + } } else { sb.append(rootException); } - } else if (error) { - boolean isLogStackTrace = isLogExceptionStackTrace.isLogStackTrace(logRecord, sb, stackTraces, location, ti); - if (isLogStackTrace) { - int i = 0; - for (StackTraceElement stackTraceElement : stackTraces) { - i++; - if (i < 5) { - continue; - } - if (acceptStackTraceElement(stackTraceElement)) { - sb.append(sep); - sb.append(" "); - sb.append(stackTraceElement.toString()); - } - } + } + } + + public void writeStackTrace(StringBuilder sb, StackTraceElement[] stackTraces) { + int i = 0; + for (StackTraceElement stackTraceElement : stackTraces) { + i++; + if (i < 5) { + continue; + } + if (acceptStackTraceElement(stackTraceElement)) { + sb.append(sep); + sb.append(" "); + sb.append(stackTraceElement.toString()); } } + } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j2Utils.java b/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j2Utils.java index 3e87db45..6281e730 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j2Utils.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/Log4j2Utils.java @@ -1,11 +1,17 @@ package net.sf.jremoterun.utilities.nonjdk.log; +import javassist.CtClass; +import javassist.CtMethod; +import net.sf.jremoterun.JrrUtils; import net.sf.jremoterun.utilities.JrrClassUtils; -import net.sf.jremoterun.utilities.nonjdk.classpath.tester.ClassPathTesterHelper; +import net.sf.jremoterun.utilities.javassist.JrrJavassistUtils; +import net.sf.jremoterun.utilities.nonjdk.classpath.inittracker.InitLogTracker; +import net.sf.jremoterun.utilities.nonjdk.classpath.tester.ClassPathTesterHelper2; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.appender.ConsoleAppender; +import org.apache.logging.log4j.core.config.AppenderControl; import org.apache.logging.log4j.core.config.Configurator; import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.logging.log4j.core.impl.Log4jContextFactory; @@ -19,11 +25,13 @@ public class Log4j2Utils { - private static final Logger log = Logger.getLogger(Log4j2Utils.class.getName()); + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); // private static final Logger log = logger; public static String sep = "\n"; +// public static boolean printMsgOnError = true; + public static boolean suppressChecks = false; public static Level logRootLevel = Level.INFO; public static org.apache.logging.log4j.core.Logger rootLogger; @@ -33,11 +41,24 @@ public class Log4j2Utils { // public static volatile Log4j2PatternLayout pl = new Log4j2ColorPatternLayout(); public static void setLog4jAppender() throws Exception { + try { + setLog4jAppenderImpl(); + }catch (Throwable e){ + InitLogTracker.defaultTracker.addException("failed set appender for log4j1",e); + throw e; + } + } + + public static void setLog4jAppenderImpl() throws Exception { + if(suppressChecks) { + suppressIsAppenderCalled(); + } checkAndFixFactory(); + JrrClassUtils.ignoreClassesForCurrentClass.add(Log4j2Utils.class.getPackage().getName()); ConsoleAppender ca = ConsoleAppender.createDefaultAppenderForLayout(pl); org.apache.logging.log4j.Logger rootLogger3 = LogManager.getRootLogger(); - ClassPathTesterHelper.checkClassInstanceOf(rootLogger3, org.apache.logging.log4j.core.Logger.class); + ClassPathTesterHelper2.createClassPathTesterHelper2().checkClassInstanceOf5(rootLogger3, org.apache.logging.log4j.core.Logger.class); rootLogger = (org.apache.logging.log4j.core.Logger) rootLogger3; LoggerConfig loggerConfig = rootLogger.get(); // loggerConfig.stop(); @@ -72,6 +93,17 @@ public static void checkAndFixFactory() throws Exception { } } + public static void suppressIsAppenderCalled() throws Exception { + InitLogTracker.defaultTracker.addLog("suppressing isRecursiveCall"); + Class clazz =AppenderControl.class; + log.info( "log4j class location = "+JrrUtils.getClassLocation(clazz)+" " + clazz.getClassLoader()); + CtClass ctClazz = JrrJavassistUtils.getClassFromDefaultPool(clazz); + CtMethod method = JrrJavassistUtils.findMethod( clazz,ctClazz,"isRecursiveCall", 0); + method.setBody("return false;"); + JrrJavassistUtils.redefineClass(ctClazz, clazz); + log.info("class redefined : "+clazz.getName()); + } + public static void setLogLevel(String loggerName, org.apache.log4j.Level level) { org.apache.log4j.Logger.getLogger(loggerName).setLevel(level); diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/Log4jMigrateUtils.java b/src/net/sf/jremoterun/utilities/nonjdk/log/Log4jMigrateUtils.java index bf79732d..1c4d1520 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/log/Log4jMigrateUtils.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/Log4jMigrateUtils.java @@ -2,6 +2,7 @@ import net.sf.jremoterun.JrrUtils; import net.sf.jremoterun.utilities.log4j.Log4jConfigurator; +import net.sf.jremoterun.utilities.nonjdk.classpath.inittracker.InitLogTracker; import org.apache.log4j.Level; import org.apache.log4j.LogManager; @@ -15,13 +16,16 @@ public class Log4jMigrateUtils { public static Level logRootLevel = Level.INFO; public static void setLog4jAppender() throws Exception { + InitLogTracker.defaultTracker.addLog("resetting log4j1 configuration"); LogManager.resetConfiguration(); + InitLogTracker.defaultTracker.addLog("log4j1 setting appender"); Log4jIntoLog4j2Converter log4j2Converter = new Log4jIntoLog4j2Converter(); org.apache.log4j.Logger.getRootLogger().addAppender(log4j2Converter); org.apache.log4j.Logger.getRootLogger().setLevel(logRootLevel); try { Log4jConfigurator.registerLog4jLoggersMBeansUsingCreateMethods(); } catch (Exception e) { + InitLogTracker.defaultTracker.addException("failed set logj41 to log4j2 converter",e); Throwable rootException = JrrUtils.getRootException(e); if (rootException instanceof ClassNotFoundException) { ClassNotFoundException cnfe = (ClassNotFoundException) rootException; diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/Sl4j2JdkLoggerConverter.java b/src/net/sf/jremoterun/utilities/nonjdk/log/Sl4j2JdkLoggerConverter.java new file mode 100644 index 00000000..6e3ccbdf --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/Sl4j2JdkLoggerConverter.java @@ -0,0 +1,13 @@ +package net.sf.jremoterun.utilities.nonjdk.log; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class Sl4j2JdkLoggerConverter { + private static final Logger log = LogManager.getLogger(); + + public static void setSl4jLoggerToLog4j2() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + Sl4jLoggerCommon.setLoggerImpl(new org.slf4j.impl.JDK14LoggerFactory()); + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/Sl4jLogger.java b/src/net/sf/jremoterun/utilities/nonjdk/log/Sl4jLogger.java index 99fdeaf5..f9395fc7 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/log/Sl4jLogger.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/Sl4jLogger.java @@ -7,13 +7,11 @@ import org.slf4j.impl.StaticLoggerBinder; public class Sl4jLogger { - private static final Logger log = LogManager.getLogger(); + public static void setSl4jLoggerToLog4j2() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { - Log4jLoggerFactory log4jLoggerLogFactory = new Log4jLoggerFactory(); - StaticLoggerBinder singleton = StaticLoggerBinder.getSingleton(); - org.slf4j.Logger instance = log4jLoggerLogFactory.getLogger("test"); - JrrClassUtils.setFieldValue(singleton, "loggerFactory", log4jLoggerLogFactory); + Sl4jLoggerCommon.setLoggerImpl(new Log4jLoggerFactory()); + } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/Sl4jLoggerCommon.groovy b/src/net/sf/jremoterun/utilities/nonjdk/log/Sl4jLoggerCommon.groovy new file mode 100644 index 00000000..688d8783 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/Sl4jLoggerCommon.groovy @@ -0,0 +1,23 @@ +package net.sf.jremoterun.utilities.nonjdk.log + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import org.slf4j.impl.StaticLoggerBinder + +import java.util.logging.Logger + +@CompileStatic +class Sl4jLoggerCommon { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + static void setStatusInited() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + JrrClassUtils.setFieldValue(org.slf4j.LoggerFactory, 'INITIALIZATION_STATE', 3); + } + + static void setLoggerImpl(org.slf4j.ILoggerFactory factoryImpl) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + StaticLoggerBinder singleton = StaticLoggerBinder.getSingleton(); + org.slf4j.Logger instance = factoryImpl.getLogger("test"); + JrrClassUtils.setFieldValue(singleton, "loggerFactory", factoryImpl); + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/threadfilter/IfAppender.java b/src/net/sf/jremoterun/utilities/nonjdk/log/threadfilter/IfAppender.java index e4b6f49d..62a2cede 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/log/threadfilter/IfAppender.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/threadfilter/IfAppender.java @@ -1,19 +1,18 @@ package net.sf.jremoterun.utilities.nonjdk.log.threadfilter; +import net.sf.jremoterun.utilities.JrrClassUtils; import net.sf.jremoterun.utilities.groovystarter.st.JdkLogFormatter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.appender.AbstractAppender; -import sun.reflect.Reflection; import timmoson.common.sertcp.TcpSession; import java.util.HashSet; public class IfAppender extends AbstractAppender { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(JrrClassUtils.getCurrentClass()); public TcpSession session; diff --git a/src/net/sf/jremoterun/utilities/nonjdk/log/threadfilter/Log4j2ThreadAppender.groovy b/src/net/sf/jremoterun/utilities/nonjdk/log/threadfilter/Log4j2ThreadAppender.groovy index e2311901..ac8c57f2 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/log/threadfilter/Log4j2ThreadAppender.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/log/threadfilter/Log4j2ThreadAppender.groovy @@ -1,6 +1,7 @@ package net.sf.jremoterun.utilities.nonjdk.log.threadfilter import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils import org.apache.logging.log4j.core.LogEvent import org.apache.logging.log4j.core.appender.AbstractAppender @@ -17,7 +18,7 @@ public abstract class Log4j2ThreadAppender extends AbstractAppender { public volatile boolean translateAllLoggersForExecuterThread = false; public Log4j2ThreadAppender() throws Exception { - super("RemoteAppender", null, null); + super("JrrAppender", null, null); loggingThread = Thread.currentThread(); } @@ -29,6 +30,11 @@ public abstract class Log4j2ThreadAppender extends AbstractAppender { loggingLogger.add(clazz.getName()); } + void setAppenderName(String name){ + JrrClassUtils.setFieldValue(this,'name',name) + } + + public boolean isPassEvent(LogEvent loggingEvent) { boolean passed = false; if (!passed && translateAllLoggers) { diff --git a/src/net/sf/jremoterun/utilities/nonjdk/memorystat/GcInfoBean.groovy b/src/net/sf/jremoterun/utilities/nonjdk/memorystat/GcInfoBean.groovy index 534d3257..40f02b48 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/memorystat/GcInfoBean.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/memorystat/GcInfoBean.groovy @@ -9,15 +9,16 @@ import groovy.transform.CompileStatic; @CompileStatic class GcInfoBean { - - private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + // implements Serializable + // can't be ser due to GarbageCollectorMXBean not ser public String gcName; public Date lastRun; - public long gcId; public long gcDuration; public com.sun.management.GarbageCollectorMXBean bean; - List infoGG = [] - + @Override + String toString() { + return gcName + } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryInfoBean.groovy b/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryInfoBean.groovy new file mode 100644 index 00000000..86c94d73 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryInfoBean.groovy @@ -0,0 +1,24 @@ +package net.sf.jremoterun.utilities.nonjdk.memorystat + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.lang.management.MemoryPoolMXBean; +import java.util.logging.Logger; + +@CompileStatic +class MemoryInfoBean { + + String name; + MemoryPoolMXBean nativeBean; + + long peek + long used + long max + float usedPercent + + @Override + String toString() { + return name + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryInstanceInfoGG.groovy b/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryInstanceInfoGG.groovy index 6719c9a3..88a544dc 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryInstanceInfoGG.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryInstanceInfoGG.groovy @@ -9,8 +9,9 @@ import groovy.transform.CompileStatic; @CompileStatic class MemoryInstanceInfoGG { + // can't be ser due to MemoryUsage not ser + - private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); String name; MemoryUsage before; MemoryUsage after; diff --git a/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryStatCollector.groovy b/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryStatCollector.groovy index b3e59071..d4dc2358 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryStatCollector.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/memorystat/MemoryStatCollector.groovy @@ -2,79 +2,139 @@ package net.sf.jremoterun.utilities.nonjdk.memorystat import com.sun.management.GcInfo import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.DefaultObjectName import net.sf.jremoterun.utilities.JrrClassUtils import net.sf.jremoterun.utilities.MBeanClient import net.sf.jremoterun.utilities.MbeanConnectionCreator -import org.junit.Test +import javax.management.MalformedObjectNameException import javax.management.ObjectInstance import javax.management.ObjectName import java.lang.management.GarbageCollectorMXBean import java.lang.management.ManagementFactory import java.lang.management.MemoryPoolMXBean import java.lang.management.MemoryUsage +import java.text.SimpleDateFormat import java.util.logging.Logger @CompileStatic -class MemoryStatCollector { +abstract class MemoryStatCollector implements DefaultObjectName { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - static Date lastCheckDate ; + public static ObjectName objectName = new ObjectName('jrr:type=memoryUsage') - static List oldGens = ['ConcurrentMarkSweep','PS MarkSweep','G1 Old Generation',] - static List oldGens2 = ['CMS Old Gen','PS Old Gen','G1 Old Gen'] + public static List oldGens = ['ConcurrentMarkSweep', 'PS MarkSweep', 'G1 Old Generation',] + public static List oldGens2 = ['CMS Old Gen', 'PS Old Gen', 'G1 Old Gen'] + public Date lastCheckDate; + public float maxUsedOldGenPercent = 70f + public float maxAllowedGcDurationMs = 5000 + public long ignoreLongGcHappenedOlderThen = 3600_000 + public static long oneMegaByte = 1000_000 - @Test - void collectGcStat4() { - System.gc() - System.runFinalization() - System.gc() - Thread.sleep(1000) - collectGcStat3() + abstract void onMsg(String msg); + + @Override + ObjectName getDefaultObjectName() throws MalformedObjectNameException { + return objectName + } + + void printBadGc(GcInfoBean gcInfoBean) { + SimpleDateFormat sdf= new SimpleDateFormat('HH:mm:ss') + String msg = "long gc duration = ${gcInfoBean.gcDuration} ms for ${gcInfoBean.bean.name} at ${sdf.format(gcInfoBean.lastRun)}" + onMsg(msg) } - static void collectGcStat3() { - List gcInfoBeans = collectGcStat() - gcInfoBeans.findAll {it.bean.lastGcInfo.duration>5000 && (lastCheckDate ==null||it.lastRun.after(lastCheckDate))}.each { - String msg = "long gc duration = ${it.gcDuration} ms for ${it.bean.name} at ${it.lastRun.format('HH:mm:ss')}" - log.info "${msg}" + boolean isBadGc(GcInfoBean it) { + if (it.bean.getLastGcInfo() == null) { + return false } - lastCheckDate = new Date() + return it.bean.lastGcInfo.duration > maxAllowedGcDurationMs && (lastCheckDate == null || it.lastRun.after(lastCheckDate)) + } + + GcInfoBean findOldGcInfoAndPrintStat() { + List gcInfoBeans = getGcStat() + List badGc = gcInfoBeans.findAll { isBadGc(it) }; + badGc.each { printBadGc(it) } + GcInfoBean gcInfoBeanLong = findOldGcInfo(gcInfoBeans) + return gcInfoBeanLong; + } + + GcInfoBean findOldGcInfo(List gcInfoBeans) { GcInfoBean gcInfoBeanLong = gcInfoBeans.find { oldGens.contains(it.bean.name) } - if(gcInfoBeanLong==null){ - throw new Exception("failed find old GC from ${gcInfoBeans.collect {it.bean.name}}") + if (gcInfoBeanLong == null) { + throw new Exception("failed find old GC from ${gcInfoBeans.collect { it.bean.name }}") } + return gcInfoBeanLong + } + + MemoryInfoBean getOldGenMemoryInfo() { MemoryPoolMXBean oldGen = ManagementFactory.getMemoryPoolMXBeans().find { oldGens2.contains(it.name) } - if(oldGen==null){ - throw new Exception("failed find old gen from ${ManagementFactory.getMemoryPoolMXBeans().collect{it.name}}") + if (oldGen == null) { + throw new Exception("failed find old gen from ${ManagementFactory.getMemoryPoolMXBeans().collect { it.name }}") } - float usedOldGen =oldGen.usage.used/oldGen.usage.max - log.info "${usedOldGen}" - log.info "${gcInfoBeanLong.lastRun}" - if( usedOldGen> 0.7){ - if(gcInfoBeanLong.lastRun.getTime()>System.currentTimeMillis()-3600_000){ - String msg = "mem used ${usedOldGen} % ${oldGen.usage.used/1000_000} mb after big gc ${gcInfoBeanLong.lastRun}" + return convertToHuman(oldGen) + } + + void collectGcStat3() { + lastCheckDate = new Date() + GcInfoBean gcInfoBeanLong = findOldGcInfoAndPrintStat() + MemoryInfoBean oldGen = getOldGenMemoryInfo() +// float usedOldGen = oldGen.usage.used / oldGen.usage.max +// log.info "${usedOldGen}" +// log.info "${gcInfoBeanLong.lastRun}" + if (oldGen.usedPercent > maxUsedOldGenPercent) { + if (gcInfoBeanLong.bean.getLastGcInfo() == null) { + log.info "high memory usage : ${oldGen.usedPercent} %, gc in old space was not run before" + } else { + if (gcInfoBeanLong.lastRun.getTime() > System.currentTimeMillis() - ignoreLongGcHappenedOlderThen) { + String msg = "mem used ${oldGen.usedPercent} % ${oldGen.used / oneMegaByte} mb after big gc ${gcInfoBeanLong.lastRun}" + onMsg(msg) + } } } log.info "gc check finished" } + List getMemoryStat() { + List beans = ManagementFactory.getMemoryPoolMXBeans() + List res = beans.collect { convertToHuman(it) } + return res + } + + MemoryInfoBean convertToHuman(MemoryPoolMXBean m) { + MemoryInfoBean memoryInfoBean = new MemoryInfoBean() + memoryInfoBean.nativeBean = m + MemoryUsage peakUsage = m.getPeakUsage() + MemoryUsage collectionUsage = m.getCollectionUsage() + MemoryUsage usage = m.getUsage() + memoryInfoBean.peek = m.getPeakUsage().getUsed() + memoryInfoBean.used = usage.getUsed() + memoryInfoBean.max = usage.getMax() + memoryInfoBean.name = m.getName() + memoryInfoBean.usedPercent = (100f*memoryInfoBean.used /memoryInfoBean.max) as float + return memoryInfoBean; + + } + - static List collectGcStat() { + List getGcStat() { List beans = ManagementFactory.getGarbageCollectorMXBeans() - List gcInfoBeans = beans.collect { convert(it as com.sun.management.GarbageCollectorMXBean) }.findAll{it!=null} + List gcInfoBeans = beans.collect { convert(it as com.sun.management.GarbageCollectorMXBean) }; + + gcInfoBeans = gcInfoBeans.findAll { it != null } return gcInfoBeans } - static GcInfoBean convert(com.sun.management.GarbageCollectorMXBean mxBean) { + GcInfoBean convert(com.sun.management.GarbageCollectorMXBean mxBean) { GcInfoBean bean = new GcInfoBean(); GcInfo lastGcInfo = mxBean.getLastGcInfo() + bean.gcName = mxBean.getName() + bean.bean = mxBean if (lastGcInfo == null) { - return null + return bean } - bean.bean = mxBean bean.lastRun = new Date(lastGcInfo.getEndTime() + ManagementFactory.getRuntimeMXBean().getStartTime()) Map memoryUsageBeforeGc = lastGcInfo.getMemoryUsageBeforeGc() Map memoryUsageAfterGc = lastGcInfo.getMemoryUsageAfterGc() @@ -84,7 +144,7 @@ class MemoryStatCollector { instanceInfo.name = it.name instanceInfo.before = memoryUsageBeforeGc.get(it.name) instanceInfo.after = memoryUsageAfterGc.get(it.name) - BigDecimal diffToNowPercent2 =(it.usage.used - instanceInfo.after.used) / it.usage.max + BigDecimal diffToNowPercent2 = (it.usage.used - instanceInfo.after.used) / it.usage.max instanceInfo.diffToNowPercent = diffToNowPercent2.floatValue(); BigDecimal freePercent2 = (instanceInfo.before.used - instanceInfo.after.used) / it.usage.max instanceInfo.freePercent = freePercent2.floatValue(); @@ -95,23 +155,18 @@ class MemoryStatCollector { } - @Test - void collectMemoryStat3() { - collectMemoryStat2() - } - - static void collectMemoryStat2() { + void collectMemoryStat2() { List beans = ManagementFactory.getMemoryPoolMXBeans() beans.each { MemoryUsage usage = it.usage - log.info "Memory ${it.name} usage : ${usage.used / 1000_000} mb" + log.info "Memory ${it.name} usage : ${usage.used / oneMegaByte} mb" } } - static List collectMemoryStat(MbeanConnectionCreator connection) { + List collectMemoryStat(MbeanConnectionCreator connection) { Set memoryMbeans = connection.getMBeanServerConnection().queryMBeans(new ObjectName("java.lang:type=MemoryPool,*"), null); ; List mbeans2 = memoryMbeans.collect { it.objectName } @@ -122,7 +177,7 @@ class MemoryStatCollector { } - static void dumpMemoryStatus(List memoryPoolMXBeans) { + void dumpMemoryStatus(List memoryPoolMXBeans) { memoryPoolMXBeans.each { MemoryUsage usage = it.getUsage() } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/GetMyHostName.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/GetMyHostName.groovy new file mode 100644 index 00000000..063e3333 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/GetMyHostName.groovy @@ -0,0 +1,16 @@ +package net.sf.jremoterun.utilities.nonjdk.net + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class GetMyHostName { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static String getMyHostname(){ + InetAddress localHost = InetAddress.getLocalHost(); + return localHost.getHostName(); + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/JrrHttpUtils.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/JrrHttpUtils.groovy new file mode 100644 index 00000000..2cf73dc1 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/JrrHttpUtils.groovy @@ -0,0 +1,173 @@ +package net.sf.jremoterun.utilities.nonjdk.net + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.net.apachehttpclient.BasicCredentialsProviderJrr +import net.sf.jremoterun.utilities.nonjdk.net.apachehttpclient.NTLMSchemeFactoryJrr +import net.sf.jremoterun.utilities.nonjdk.net.apachehttpclient.ProxyAuthenticationStrategyJrr +import net.sf.jremoterun.utilities.nonjdk.net.ssl.SslChecksDisable +import net.sf.jremoterun.utilities.nonjdk.net.ssl.SslHostNameVerifierAllowAll +import org.apache.http.Header +import org.apache.http.auth.AuthSchemeProvider +import org.apache.http.auth.AuthScope +import org.apache.http.auth.NTCredentials +import org.apache.http.auth.UsernamePasswordCredentials +import org.apache.http.client.AuthenticationStrategy +import org.apache.http.client.config.AuthSchemes +import org.apache.http.client.methods.CloseableHttpResponse +import org.apache.http.client.methods.HttpGet +import org.apache.http.config.Registry +import org.apache.http.config.RegistryBuilder +import org.apache.http.conn.ssl.SSLConnectionSocketFactory +import org.apache.http.conn.ssl.TrustStrategy +import org.apache.http.impl.client.BasicCredentialsProvider +import org.apache.http.impl.client.CloseableHttpClient +import org.apache.http.impl.client.HttpClientBuilder +import org.apache.http.impl.client.HttpClients +import org.apache.http.impl.conn.SystemDefaultRoutePlanner +import org.apache.http.ssl.SSLContextBuilder + +import java.security.cert.CertificateException +import java.security.cert.X509Certificate +import java.util.logging.Logger + +/** + * @see net.sf.jremoterun.utilities.nonjdk.maven.http.JrrMavenHttpUtils + */ +@CompileStatic +public class JrrHttpUtils { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public HttpClientBuilder httpClientBuilder = HttpClients.custom() + public CloseableHttpClient httpClient1; + public AuthSchemeProvider ntlmSchemeFactory = new NTLMSchemeFactoryJrr(this) + public AuthenticationStrategy proxyAuthenticationStrategy = new ProxyAuthenticationStrategyJrr(); + public BasicCredentialsProvider credentialsProvider1 = new BasicCredentialsProviderJrr(); + + + void createClient() { + httpClient1 = httpClientBuilder.build(); + } + + + + void setCred(NTCredentials credentials , String proxyHost, int proxyPort) { + credentialsProvider1.setCredentials(new AuthScope(proxyHost, proxyPort), credentials); + InetAddress name = InetAddress.getByName(proxyHost) + String ipAddress = name.getHostAddress() + if(ipAddress!=proxyHost){ + credentialsProvider1.setCredentials(new AuthScope(ipAddress, proxyPort), credentials); + } + } + + NTCredentials createNTCredentials(String user,String password,String domain){ + return new NTCredentials(user,password,null,domain); + } + + + /** + * Set ProxySelector.getDefault() before !! + */ + void addProxyNtlmAuth3(NTCredentials credentials, String proxyHost, int proxyPort) { + setCred(credentials,proxyHost,proxyPort) + httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider1) + httpClientBuilder.setProxyAuthenticationStrategy(proxyAuthenticationStrategy) + Registry authSchemeProviderRegistry = RegistryBuilder. create().register(AuthSchemes.NTLM, ntlmSchemeFactory).build(); + httpClientBuilder.setDefaultAuthSchemeRegistry(authSchemeProviderRegistry) + setRouterPlanner() + } + + void setRouterPlanner() { + SystemDefaultRoutePlanner routePlanner = new SystemDefaultRoutePlanner(ProxySelector.getDefault()) + httpClientBuilder.setRoutePlanner(routePlanner) + } + + void addRedirectionNon() { + httpClientBuilder.setRedirectStrategy(new RedirectStrategyNone()) + } + + + void sslCheckDisable() { + httpClientBuilder.setSSLHostnameVerifier(new SslHostNameVerifierAllowAll()); + httpClientBuilder.setSSLSocketFactory(new SSLConnectionSocketFactory(SslChecksDisable.createAllTrustSslContext())); + } + + + + + +// @Deprecated +// void addProxyNtlmAuth(String user, String passport, String domain, String proxyHost, int proxyPort) { +// NTCredentials credentials = new NTCredentials(user, passport, null, domain) +// setCred(credentials,proxyHost,proxyPort) +// HttpHost proxyHttpHost1 = new HttpHost(proxyHost, proxyPort); +// httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider1) +// httpClientBuilder.setProxy(proxyHttpHost1) +// httpClientBuilder.setProxyAuthenticationStrategy(proxyAuthenticationStrategy) +// Registry authSchemeProviderRegistry = RegistryBuilder. create().register(AuthSchemes.NTLM, ntlmSchemeFactory).build(); +// httpClientBuilder.setDefaultAuthSchemeRegistry(authSchemeProviderRegistry) +// } + + List getCertificatesFromHost(String host) { + X509Certificate[] chains + SSLContextBuilder builder = new SSLContextBuilder(); + TrustStrategy trustStrategy = new TrustStrategy() { + + @Override + boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { + chains = chain; + return true; + } + } + // for cert auth put private key certificate here for loadTrustMaterial method + builder.loadTrustMaterial(null, trustStrategy); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); + + httpClientBuilder.setSSLSocketFactory(sslsf); + + String urll + if (host.startsWith('https://')) { + urll = host + } else { + urll = "https://${host}" + } + HttpGet httpGet = new HttpGet(urll); + createClient(); + CloseableHttpResponse response = httpClient1.execute(httpGet); + response.close() + + if (chains == null) { + throw new NullPointerException("No certificates") + } + return chains.toList(); + } + + + + @Deprecated + void createClientCred(String host, int port, String username, String password) { + BasicCredentialsProvider basicCredentialsProvider = new BasicCredentialsProvider() + basicCredentialsProvider.setCredentials(new AuthScope(host, port), new UsernamePasswordCredentials(username, password)); + httpClientBuilder.setDefaultCredentialsProvider(basicCredentialsProvider); + } + + + Header getHeader(URL url, String headerName) { + createClient(); + HttpGet httpGet = new HttpGet(url.toString()); + CloseableHttpResponse response = httpClient1.execute(httpGet); + try { + assert response.getStatusLine().getStatusCode() == 200: url + Header[] headers = response.getAllHeaders() + Header header = response.getFirstHeader(headerName) + if (header == null) { + throw new IllegalStateException("header not found ${headerName}, headers : ${headers.toList().collect { it.getName() }} ${url}") + } + return header + } finally { + response.close() + } + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/NetDebugEnable.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/NetDebugEnable.groovy new file mode 100644 index 00000000..44840d4b --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/NetDebugEnable.groovy @@ -0,0 +1,18 @@ +package net.sf.jremoterun.utilities.nonjdk.net + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class NetDebugEnable { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + +// https://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/ReadDebug.html + static void enableDebug() { + System.setProperty('javax.net.debug', 'ssl:handshake:verbose:keymanager:trustmanager') + System.setProperty('javax.net.debug', 'all') + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/ProxyTrackerI.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/ProxyTrackerI.groovy new file mode 100644 index 00000000..986d1b82 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/ProxyTrackerI.groovy @@ -0,0 +1,16 @@ +package net.sf.jremoterun.utilities.nonjdk.net + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +interface ProxyTrackerI { + + + void accessRequested(URI uri,boolean proxyUsed); + + + void accessRequested(String host,boolean proxyUsed); + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/ProxyTrackerStat.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/ProxyTrackerStat.groovy new file mode 100644 index 00000000..42e089a6 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/ProxyTrackerStat.groovy @@ -0,0 +1,30 @@ +package net.sf.jremoterun.utilities.nonjdk.net + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +@CompileStatic +class ProxyTrackerStat implements ProxyTrackerI { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public Map firstAccess = new ConcurrentHashMap<>() + public Map lastAccess = new ConcurrentHashMap<>() + + @Override + void accessRequested(URI uri, boolean proxyUsed) { + accessRequested(uri.getHost(),proxyUsed) + } + + @Override + void accessRequested(String host, boolean proxyUsed) { + Date date = new Date() + if(!firstAccess.containsKey(host)){ + firstAccess.put(host,date) + } + lastAccess.put(host,date) + + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/RedirectStrategyNone.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/RedirectStrategyNone.groovy new file mode 100644 index 00000000..4b75383f --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/RedirectStrategyNone.groovy @@ -0,0 +1,29 @@ +package net.sf.jremoterun.utilities.nonjdk.net + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.http.HttpRequest +import org.apache.http.HttpResponse +import org.apache.http.ProtocolException +import org.apache.http.client.RedirectStrategy +import org.apache.http.client.methods.HttpUriRequest +import org.apache.http.protocol.HttpContext; + +import java.util.logging.Logger; + +@CompileStatic +class RedirectStrategyNone implements RedirectStrategy{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException { + log.info "isRedirected ${response}" + return false + } + + @Override + HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException { + log.info "getRedirect ${response}" + return null + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/BasicCredentialsProviderJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/BasicCredentialsProviderJrr.groovy new file mode 100644 index 00000000..de1f1454 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/BasicCredentialsProviderJrr.groovy @@ -0,0 +1,34 @@ +package net.sf.jremoterun.utilities.nonjdk.net.apachehttpclient + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.http.auth.AuthScope +import org.apache.http.auth.Credentials +import org.apache.http.impl.client.BasicCredentialsProvider; + +import java.util.logging.Logger; + +@CompileStatic +class BasicCredentialsProviderJrr extends BasicCredentialsProvider{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void setCredentials(AuthScope authscope, Credentials credentials) { + log.info "${authscope} ${credentials}" + super.setCredentials(authscope, credentials) + } + + @Override + Credentials getCredentials(AuthScope authscope) { + Credentials credentials = super.getCredentials(authscope) + log.info "${authscope} ${credentials}" + return credentials; + } + + @Override + void clear() { + log.info "clear" + super.clear() + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/NTLMSchemeFactoryJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/NTLMSchemeFactoryJrr.groovy new file mode 100644 index 00000000..6b892f7a --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/NTLMSchemeFactoryJrr.groovy @@ -0,0 +1,37 @@ +package net.sf.jremoterun.utilities.nonjdk.net.apachehttpclient + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.net.JrrHttpUtils +import org.apache.http.auth.AuthScheme +import org.apache.http.impl.auth.NTLMSchemeFactory +import org.apache.http.params.HttpParams +import org.apache.http.protocol.HttpContext; + +import java.util.logging.Logger; + +@CompileStatic +class NTLMSchemeFactoryJrr extends NTLMSchemeFactory{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public JrrHttpUtils jrrHttpUtils; + public volatile NTLMSchemeJrr lastNTLMSchemeJrr; + + NTLMSchemeFactoryJrr(JrrHttpUtils jrrHttpUtils) { + this.jrrHttpUtils = jrrHttpUtils + } + + @Override + AuthScheme newInstance(HttpParams params) { + NTLMSchemeJrr ntlmJrr = new NTLMSchemeJrr(jrrHttpUtils) + lastNTLMSchemeJrr = ntlmJrr + return ntlmJrr + } + + @Override + AuthScheme create(HttpContext context) { + NTLMSchemeJrr ntlmJrr = new NTLMSchemeJrr(jrrHttpUtils) + lastNTLMSchemeJrr = ntlmJrr + return ntlmJrr + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/NTLMSchemeJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/NTLMSchemeJrr.groovy new file mode 100644 index 00000000..7c500f28 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/NTLMSchemeJrr.groovy @@ -0,0 +1,49 @@ +package net.sf.jremoterun.utilities.nonjdk.net.apachehttpclient + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.nonjdk.net.JrrHttpUtils +import org.apache.http.Header +import org.apache.http.HttpRequest +import org.apache.http.auth.AuthenticationException +import org.apache.http.auth.Credentials +import org.apache.http.impl.auth.NTLMEngine +import org.apache.http.impl.auth.NTLMScheme + +import java.util.logging.Logger; + +@CompileStatic +class NTLMSchemeJrr extends NTLMScheme{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static ClRef clRefEngineImpl = new ClRef('org.apache.http.impl.auth.NTLMEngineImpl') + + public JrrHttpUtils jrrHttpUtils; + + NTLMSchemeJrr(JrrHttpUtils jrrHttpUtils) { + this.jrrHttpUtils = jrrHttpUtils + } + + NTLMSchemeJrr(NTLMEngine engine, JrrHttpUtils jrrHttpUtils) { + super(engine) + this.jrrHttpUtils = jrrHttpUtils + } + + @Override + Header authenticate(Credentials credentials, HttpRequest request) throws AuthenticationException { + log.info "proxy auth state = ${getState1()}" + return super.authenticate(credentials, request) + } + + public Object getState1(){ + return JrrClassUtils.getFieldValue(this,'state') + } + + + + static NTLMEngine createNTLMEngineImpl(){ + clRefEngineImpl.newInstance3() as NTLMEngine + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/ProxyAuthenticationStrategyJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/ProxyAuthenticationStrategyJrr.groovy new file mode 100644 index 00000000..457f1f03 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/apachehttpclient/ProxyAuthenticationStrategyJrr.groovy @@ -0,0 +1,50 @@ +package net.sf.jremoterun.utilities.nonjdk.net.apachehttpclient + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.apache.http.Header +import org.apache.http.HttpHost +import org.apache.http.HttpResponse +import org.apache.http.auth.AuthOption +import org.apache.http.auth.AuthScheme +import org.apache.http.auth.MalformedChallengeException +import org.apache.http.impl.client.ProxyAuthenticationStrategy +import org.apache.http.protocol.HttpContext; + +import java.util.logging.Logger; + +@CompileStatic +class ProxyAuthenticationStrategyJrr extends ProxyAuthenticationStrategy{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + boolean isAuthenticationRequested(HttpHost authhost, HttpResponse response, HttpContext context) { + return super.isAuthenticationRequested(authhost, response, context) + } + + @Override + Map getChallenges(HttpHost authhost, HttpResponse response, HttpContext context) throws MalformedChallengeException { + Map challenges = super.getChallenges(authhost, response, context) + log.info "${authhost} ${challenges}" + return challenges + } + + @Override + Queue select(Map challenges, HttpHost authhost, HttpResponse response, HttpContext context) throws MalformedChallengeException { + Queue select = super.select(challenges, authhost, response, context) + log.info "${challenges} ${select}" + return select + } + + @Override + void authSucceeded(HttpHost authhost, AuthScheme authScheme, HttpContext context) { + log.info "good ${authhost}" + super.authSucceeded(authhost, authScheme, context) + } + + @Override + void authFailed(HttpHost authhost, AuthScheme authScheme, HttpContext context) { + log.info "failed ${authhost}" + super.authFailed(authhost, authScheme, context) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/okhttp/NTLMAuthenticator.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/okhttp/NTLMAuthenticator.groovy new file mode 100644 index 00000000..f87c0233 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/okhttp/NTLMAuthenticator.groovy @@ -0,0 +1,110 @@ +package net.sf.jremoterun.utilities.nonjdk.net.okhttp + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.net.apachehttpclient.NTLMSchemeJrr +import okhttp3.Authenticator; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.Route; +import okhttp3.Headers; +import org.apache.http.auth.AUTH +import org.apache.http.impl.auth.NTLMEngine +import org.apache.http.impl.auth.NTLMEngineException + +import java.util.logging.Logger + +/** see also + * @see sun.net.www.protocol.http.ntlm.NTLMAuthentication* @see jcifs.ntlmssp.Type1Message* https://github.com/square/okhttp/issues/206 + */ + +@CompileStatic +class NTLMAuthenticator implements Authenticator { + + private static Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static String okSpecialHeader = "OkHttp-Preemptive" + public static int maxCount = 5 + + public NTLMEngine engine = NTLMSchemeJrr.createNTLMEngineImpl(); + public String domain; + public String username; + public String password; + public String ntlmMsg1; + public String workstation; + public NtlmState state = NtlmState.UNINITIATED; + public int countt = 0 + + + public NTLMAuthenticator(String username, String password, String domain, String workstation) throws NTLMEngineException { + this.domain = domain; + this.username = username; + this.password = password; + ntlmMsg1 = engine.generateType1Msg(domain, null); + this.workstation = workstation + } + + + @Override + Request authenticate(Route route, Response response) throws IOException { + String headerValue = authenticateImpl(response) + return response.request().newBuilder().header(AUTH.PROXY_AUTH_RESP, "NTLM ${headerValue}").build(); + } + + + String authenticateImpl(Response response) throws IOException { + if (response.code() != 407) { + throw new IOException("bad code ${response.code()}"); + } + Headers headers = response.headers(); + log.info "state = ${state}, headers = ${headers}" + final List proxyAuthHeaders = headers.values(AUTH.PROXY_AUTH); + if (proxyAuthHeaders.size() == 0) { + throw new IOException("No ${AUTH.PROXY_AUTH} header : ${headers}"); + } + if (state == NtlmState.MSG_TYPE3_GENERATED || state == NtlmState.UNINITIATED) { + if (proxyAuthHeaders.size() == 1) { + if (proxyAuthHeaders.first() == okSpecialHeader) { + log.info "restarting and send first msg " + state = NtlmState.MSG_TYPE1_GENERATED; + return ntlmMsg1 + } + } + } + if (proxyAuthHeaders.contains("NTLM")) { + if (state != NtlmState.UNINITIATED) { + log.info("Wrong state : ${state}") + countt++ + if (countt > maxCount) { + throw new Exception("Wrong state : ${state}") + } + } + log.info("generate first"); + state = NtlmState.MSG_TYPE1_GENERATED; + return ntlmMsg1 + } + if (state != NtlmState.MSG_TYPE1_GENERATED) { + throw new IOException("Wrong state : ${state}") + } + List ntlmaaa = proxyAuthHeaders.findAll { it.startsWith('NTLM ') } + if (ntlmaaa.size() == 0) { + return onNoHeaderFound(response, headers, proxyAuthHeaders) + } + String ntlmMsg3 = ntlmaaa.first(); + return doType3(ntlmMsg3) + } + + String doType3(String ntlmMsg3) { + String substring = ntlmMsg3.substring(5); + state = NtlmState.MSG_TYPE2_RECEVIED; + log.info "got ${state}, generating type3 msgs .." + ntlmMsg3 = engine.generateType3Msg(username, password, domain, workstation, substring); + state = NtlmState.MSG_TYPE3_GENERATED; + log.info "sending ${state}" + return ntlmMsg3 + } + + String onNoHeaderFound(Response response, Headers headers, List proxyAuthHeaders) { + throw new IOException("NTLM header not found ${proxyAuthHeaders}") + } +} \ No newline at end of file diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/okhttp/NtlmState.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/okhttp/NtlmState.groovy new file mode 100644 index 00000000..f0c0721c --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/okhttp/NtlmState.groovy @@ -0,0 +1,17 @@ +package net.sf.jremoterun.utilities.nonjdk.net.okhttp + +import groovy.transform.CompileStatic; + + +@CompileStatic +enum NtlmState { + + UNINITIATED, + CHALLENGE_RECEIVED, + MSG_TYPE1_GENERATED, + MSG_TYPE2_RECEVIED, + MSG_TYPE3_GENERATED, + FAILED, + + +} \ No newline at end of file diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslAllTrustManager.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslAllTrustManager.groovy new file mode 100644 index 00000000..43ca7000 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslAllTrustManager.groovy @@ -0,0 +1,39 @@ +package net.sf.jremoterun.utilities.nonjdk.net.ssl + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import javax.net.ssl.SSLContext +import javax.net.ssl.TrustManager +import javax.net.ssl.X509TrustManager +import java.security.SecureRandom +import java.security.cert.CertificateException +import java.security.cert.X509Certificate; +import java.util.logging.Logger; + + +/** + * @see org.apache.commons.net.util.TrustManagerUtils#getAcceptAllTrustManager() + */ +@CompileStatic +class SslAllTrustManager implements X509TrustManager { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + + + @Override + void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + + } + + @Override + void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + + } + + @Override + X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0] + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslChecksDisable.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslChecksDisable.groovy new file mode 100644 index 00000000..92729303 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslChecksDisable.groovy @@ -0,0 +1,43 @@ +package net.sf.jremoterun.utilities.nonjdk.net.ssl + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import javax.net.ssl.HostnameVerifier +import javax.net.ssl.HttpsURLConnection +import javax.net.ssl.SSLContext +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.TrustManager +import java.security.SecureRandom +import java.util.logging.Logger; + +@CompileStatic +class SslChecksDisable { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public static SSLSocketFactory defaultSSLSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory() + public static HostnameVerifier hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier() + public static SSLContext sslContextDefault = SSLContext.getDefault() + public static String defaultProtocol = 'TLS' + + + static void allowAll() { + HttpsURLConnection.setDefaultHostnameVerifier(new SslHostNameVerifierAllowAll()) + SSLContext sSLContext = createAllTrustSslContext() + SSLContext.setDefault(sSLContext) + HttpsURLConnection.setDefaultSSLSocketFactory(sSLContext.getSocketFactory()) + } + + static SSLContext createAllTrustSslContext(){ + TrustManager trustManager = new SslAllTrustManager() + TrustManager[] trustManagers = [trustManager] + + SSLContext sSLContext = SSLContext.getInstance(defaultProtocol) + sSLContext.init(null, trustManagers, new SecureRandom()) + return sSLContext; + } + + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslConnectionInspect.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslConnectionInspect.groovy new file mode 100644 index 00000000..02cef58a --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslConnectionInspect.groovy @@ -0,0 +1,74 @@ +package net.sf.jremoterun.utilities.nonjdk.net.ssl; + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import javax.net.ssl.SSLContext +import javax.net.ssl.SSLSession +import javax.net.ssl.SSLSocket +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.TrustManager +import javax.net.ssl.X509TrustManager +import java.security.cert.CertificateException +import java.security.cert.X509Certificate; +import java.util.logging.Logger; + +@CompileStatic +class SslConnectionInspect { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static String tlsProtocolVersion = 'TLSv1.2' + public List chains = [] + public SSLContext sslContext + public SSLSocketFactory sslSocketFactory; + public SSLSocket socket; + + public X509TrustManager trustManager = new X509TrustManager() { + + @Override + void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + chains.addAll(chain.toList()) + } + + @Override + void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + chains.addAll(chain.toList()) + } + + @Override + X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0] + } + } + + void createSslContext() { + sslContext = SSLContext.getInstance(tlsProtocolVersion); + TrustManager[] tms = [trustManager] + sslContext.init(null, tms, null) + } + + void prepare() { + if (sslContext == null) { + createSslContext() + } + if (sslSocketFactory == null) { + sslSocketFactory = sslContext.getSocketFactory() + } + + } + + void check(String hostName, int port) { + prepare() + socket = sslSocketFactory.createSocket(hostName, port) as SSLSocket; + startHandshake() + } + + void startHandshake() { + socket.startHandshake() + } + + + SSLSession getSslSession(){ + socket.getSession() + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslHostNameVerifierAllowAll.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslHostNameVerifierAllowAll.groovy new file mode 100644 index 00000000..beedf76f --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/SslHostNameVerifierAllowAll.groovy @@ -0,0 +1,29 @@ +package net.sf.jremoterun.utilities.nonjdk.net.ssl + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import javax.net.ssl.HostnameVerifier +import javax.net.ssl.HttpsURLConnection +import javax.net.ssl.SSLContext +import javax.net.ssl.SSLSession +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.TrustManager +import java.security.SecureRandom; +import java.util.logging.Logger; + +/** + @see org.apache.http.conn.ssl.NoopHostnameVerifier + */ +@CompileStatic +class SslHostNameVerifierAllowAll implements HostnameVerifier { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + @Override + boolean verify(String s, SSLSession sslSession) { + return true + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/bc/SslConnectionInspectBc.groovy b/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/bc/SslConnectionInspectBc.groovy new file mode 100644 index 00000000..ae4c3a0d --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/net/ssl/bc/SslConnectionInspectBc.groovy @@ -0,0 +1,61 @@ +package net.sf.jremoterun.utilities.nonjdk.net.ssl.bc + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.bouncycastle.tls.DefaultTlsClient +import org.bouncycastle.tls.ServerOnlyTlsAuthentication +import org.bouncycastle.tls.TlsAuthentication +import org.bouncycastle.tls.TlsClient +import org.bouncycastle.tls.TlsClientProtocol +import org.bouncycastle.tls.TlsServerCertificate +import org.bouncycastle.tls.crypto.TlsCrypto +import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto + +import java.security.SecureRandom; +import java.util.logging.Logger; + +@CompileStatic +class SslConnectionInspectBc { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + // Depends on: +// bctls_jdk15to18, +// bcprov_jdk15to18, +// bcutil_jdk15to18, + + public List serverCertificates = [] + public Socket socket; + public TlsClientProtocol tlsClientProtocol + public TlsCrypto tlsCrypto; + public TlsClient tlsClient + + void check(String host, int port) { + socket = new Socket(host, port); + connect() + } + + void connect() { + tlsClientProtocol = new TlsClientProtocol( + socket.getInputStream(), socket.getOutputStream()); + if (tlsCrypto == null) { + tlsCrypto = new BcTlsCrypto(new SecureRandom()) + } + if (tlsClient == null) { + tlsClient = new DefaultTlsClient(tlsCrypto) { + public TlsAuthentication getAuthentication() throws IOException { + return new ServerOnlyTlsAuthentication() { + + @Override + void notifyServerCertificate(TlsServerCertificate serverCertificate) throws IOException { + serverCertificates.add(serverCertificate) + } + }; + } + } + } + tlsClientProtocol.connect(tlsClient); + + //InputStream stream = tlsClientProtocol.getInputStream() + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/packun/Pack.groovy b/src/net/sf/jremoterun/utilities/nonjdk/packun/Pack.groovy index 87cd8b2d..5c5f2d2e 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/packun/Pack.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/packun/Pack.groovy @@ -10,6 +10,7 @@ import net.sf.jremoterun.utilities.nonjdk.store.ListStore import org.apache.commons.io.FileUtils import org.zeroturnaround.zip.ZipUtil +import java.text.SimpleDateFormat import java.util.logging.Logger @EqualsAndHashCode @@ -37,7 +38,7 @@ class Pack { static String infoFile = 'info.groovy' void packAllWithDate() { - String date = new Date().format('yyyy-MM-dd--HH-mm') + String date = new SimpleDateFormat('yyyy-MM-dd--HH-mm').format(new Date()) baseDir = baseDir.child(date) baseDir.mkdir() assert baseDir.exists() diff --git a/src/net/sf/jremoterun/utilities/nonjdk/packun/Unpack.groovy b/src/net/sf/jremoterun/utilities/nonjdk/packun/Unpack.groovy index 3813f28c..0ce9f755 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/packun/Unpack.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/packun/Unpack.groovy @@ -15,21 +15,22 @@ class Unpack { File baseDir List packInfos + File backupDir - Unpack(File baseDir) { - this(baseDir.child(Pack.infoFile),baseDir) + Unpack(File baseDir,File backupDir) { + this(baseDir.child(Pack.infoFile),baseDir,backupDir) } - Unpack(File configFile, File baseDir) { + Unpack(File configFile, File baseDir,File backupDir) { ListStore config =new ListStore(configFile) List packInfos = config.loadsettings() this.packInfos = packInfos this.baseDir = baseDir } - static Unpack downloadFromRemoteHost(SshConSet3 sshConSet3, String remoteDir,File localDir){ + static Unpack downloadFromRemoteHost(SshConSet3 sshConSet3, String remoteDir,File localDir,File backupDir){ sshConSet3.createSftpUtils().sftp2.copyRemoteDirectory(remoteDir,localDir.absolutePath,true,false,true,null) - return new Unpack(localDir) + return new Unpack(localDir,backupDir) } void unpackAll(){ @@ -48,13 +49,24 @@ class Unpack { assert zipFile.exists() if(packInfo.unzipLocation.exists()){ assert packInfo.unzipLocation.directory - FileUtils.cleanDirectory(packInfo.unzipLocation) + if(packInfo.unzipLocation.listFiles().length>0){ + rename(packInfo) + } +// FileUtils.cleanDirectory(packInfo.unzipLocation) } packInfo.unzipLocation.mkdirs() assert packInfo.unzipLocation.exists() handlePackImpl(zipFile,packInfo) } + + void rename(PackInfo packInfo){ + File backupdir2=backupDir.child(packInfo.zipLocation) + assert !backupdir2.exists() + File unzipLoc =packInfo.unzipLocation + assert unzipLoc.renameTo(backupdir2) + } + void handlePackImpl(File zipFile,PackInfo packInfo){ ZipUtil.unpack(zipFile,packInfo.unzipLocation) } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/JustStackTrace.groovy b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/JustStackTrace.groovy new file mode 100644 index 00000000..60e483a7 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/JustStackTrace.groovy @@ -0,0 +1,12 @@ +package net.sf.jremoterun.utilities.nonjdk.problemchecker + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class JustStackTrace extends Exception{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollector.groovy b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollector.groovy new file mode 100644 index 00000000..33b83c2d --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollector.groovy @@ -0,0 +1,66 @@ +package net.sf.jremoterun.utilities.nonjdk.problemchecker + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.JrrUtilities + +import java.util.logging.Logger + +@CompileStatic +class ProblemCollector implements ProblemCollectorI { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + List list = [] + + @Override + void addProblemImpl(ProblemInfo problemInfo) { + log.info "found problem ${problemInfo}" + list.add(problemInfo) + } + + + String printProblemsSummary() { + if (list.size() == 0) { + log.info "no problems" + return null + } else { + String problems = list.collect { it.toString() }.join('\n') + log.info "found ${list.size()} problems: \n${problems}" + return problems + } + } + + void checkIfProblemExistAndThrowException() { + String problemsSummary = printProblemsSummary() + if (list.size() == 1) { + ProblemInfo problemInfo = list[0] +// if(problemInfo.stackTrace ==null||problemInfo.stackTrace instanceof JustStackTrace){ + throw new ProblemFoundException(problemInfo) +// }else{ +// +// } + } + if (list.size() > 1) { + throw new Exception(problemsSummary) + } + } + + boolean checkIfProblemExistAndShowException() { + String problemsSummary = printProblemsSummary() + int size = list.size() + if(size==0){ + return true + } + if (size == 1) { + ProblemInfo problemInfo = list[0] + JrrUtilities.showException(problemInfo.msg,problemInfo.stackTrace) + } + if (size > 1) { + JrrUtilities.showException(problemsSummary,new Exception(problemsSummary)) + } + return false + } + + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollectorI.groovy b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollectorI.groovy new file mode 100644 index 00000000..b6a94734 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollectorI.groovy @@ -0,0 +1,14 @@ +package net.sf.jremoterun.utilities.nonjdk.problemchecker + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.util.logging.Logger + +@CompileStatic +interface ProblemCollectorI { + + void addProblemImpl(ProblemInfo problemInfo) + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollectorIThrowImmediate.groovy b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollectorIThrowImmediate.groovy new file mode 100644 index 00000000..e8bf40dc --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemCollectorIThrowImmediate.groovy @@ -0,0 +1,15 @@ +package net.sf.jremoterun.utilities.nonjdk.problemchecker + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ProblemCollectorIThrowImmediate implements ProblemCollectorI{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + void addProblemImpl(ProblemInfo problemInfo) { + throw new ProblemFoundException(problemInfo) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemFoundException.groovy b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemFoundException.groovy new file mode 100644 index 00000000..7c6a5607 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemFoundException.groovy @@ -0,0 +1,29 @@ +package net.sf.jremoterun.utilities.nonjdk.problemchecker + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ProblemFoundException extends Exception{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + ProblemInfo problemInfo + + ProblemFoundException( ProblemInfo problemInfo) { + super(problemInfo.msg) + this.problemInfo = problemInfo + if(problemInfo.stackTrace==null || problemInfo.stackTrace instanceof JustStackTrace){ + + }else{ + initCause(problemInfo.stackTrace) + } + } + + + + + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemHelper.groovy b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemHelper.groovy new file mode 100644 index 00000000..8e85bdb1 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemHelper.groovy @@ -0,0 +1,32 @@ +package net.sf.jremoterun.utilities.nonjdk.problemchecker + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ProblemHelper { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + ProblemCollectorI problemCollectorI + + void addProblem2(String msg,Throwable stackTrace){ + ProblemInfo problemInfo = new ProblemInfo() + problemInfo.msg = msg + problemInfo.stackTrace = stackTrace + addProblemImpl(problemInfo) + } + + void addProblem(String msg){ + ProblemInfo problemInfo = new ProblemInfo() + problemInfo.msg = msg + problemInfo.stackTrace = new Exception(msg) + addProblemImpl(problemInfo) + } + + void addProblemImpl(ProblemInfo problemInfo){ + problemCollectorI.addProblemImpl(problemInfo) + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemInfo.groovy b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemInfo.groovy new file mode 100644 index 00000000..a91f97df --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/problemchecker/ProblemInfo.groovy @@ -0,0 +1,22 @@ +package net.sf.jremoterun.utilities.nonjdk.problemchecker + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class ProblemInfo { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + String msg + + Throwable stackTrace; + + @Override + String toString() { + if (stackTrace == null || stackTrace instanceof JustStackTrace) { + return msg + } + return "${msg} ${stackTrace}" + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfApplication.groovy b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfApplication.groovy new file mode 100644 index 00000000..bf72a8ca --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfApplication.groovy @@ -0,0 +1,66 @@ +package net.sf.jremoterun.utilities.nonjdk.quickfixsender + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import quickfix.Application +import quickfix.DoNotSend +import quickfix.FieldNotFound +import quickfix.IncorrectDataFormat +import quickfix.IncorrectTagValue +import quickfix.Message +import quickfix.RejectLogon +import quickfix.SessionID +import quickfix.UnsupportedMessageType + +import java.awt.Color; +import java.util.logging.Logger; + +@CompileStatic +class JrrQfApplication implements Application { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + QfRstaRunnerWithStackTrace runner; + + JrrQfApplication(QfRstaRunnerWithStackTrace runner) { + this.runner = runner + } + + @Override + void onCreate(SessionID sessionId) { + + } + + @Override + void onLogon(SessionID sessionId) { + runner.statusField.setText("Logon") + runner.statusField.setForeground(Color.GREEN) + } + + @Override + void onLogout(SessionID sessionId) { + runner.statusField.setText("Logout") + runner.statusField.setForeground(Color.RED) + } + + @Override + void toAdmin(Message message, SessionID sessionId) { + runner.addMessageToView(message, true) + } + + @Override + void toApp(Message message, SessionID sessionId) throws DoNotSend { + runner.addMessageToView(message, true) + } + + + + @Override + void fromAdmin(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon { + runner.addMessageToView(message, false) + } + + @Override + void fromApp(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType { + runner.addMessageToView(message, false) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfDataHolder.groovy b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfDataHolder.groovy new file mode 100644 index 00000000..8c57cfec --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfDataHolder.groovy @@ -0,0 +1,71 @@ +package net.sf.jremoterun.utilities.nonjdk.quickfixsender + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.timer.TimerPeriod +import quickfix.Connector +import quickfix.DefaultMessageFactory +import quickfix.Dictionary +import quickfix.LogFactory +import quickfix.MemoryStoreFactory +import quickfix.MessageFactory +import quickfix.MessageStoreFactory +import quickfix.Session +import quickfix.SessionID +import quickfix.SessionSettings + +import java.text.SimpleDateFormat; +import java.util.logging.Logger +import java.util.regex.Pattern; + +@CompileStatic +class JrrQfDataHolder { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public QfRstaRunnerWithStackTrace t + public JrrQfApplication application + public JrrQfDataHolder d = this + + + public Pattern seqNumMismatch = Pattern.compile('MsgSeqNum too low, expecting (\\d+) but received (\\d)') + + public boolean autoFixSeqNum = true + + + public SimpleDateFormat sdf = new SimpleDateFormat('HH:mm:ss') + + public volatile int modificationsCount = 100; + + public final Object disconnectLock = new Object() + + public Date lastMsgSend = new Date() + public long autoDisconnectTimeInSec = 60 * 10; + public static char fixMsgNativeSep = '\u0001'; + public char humanSep = '|'; + + + public MessageStoreFactory storeFactory = new MemoryStoreFactory(); + public LogFactory logFactory + public MessageFactory messageFactory = new DefaultMessageFactory(); + + public Session qfSession + + public Connector connector; + + public Dictionary dictionary; + + public SessionID sessionID; + public Properties prop2; + public SessionSettings settings; + + public TimerPeriod timerPeriod + public JrrQfSessionFactory sessionFactory +// public DefaultSessionScheduleFactory sessionScheduleFactory + public int DEFAULT_QUEUE_CAPACITY = 10000; + public boolean acceptor + + JrrQfDataHolder(QfRstaRunnerWithStackTrace t) { + this.t = t + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfHelper.groovy b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfHelper.groovy new file mode 100644 index 00000000..8a84b040 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfHelper.groovy @@ -0,0 +1,332 @@ +package net.sf.jremoterun.utilities.nonjdk.quickfixsender + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.rstarunner.RstaScriptHelper +import net.sf.jremoterun.utilities.nonjdk.timer.TimerPeriod +import quickfix.Connector +import quickfix.DataDictionary +import quickfix.DefaultDataDictionaryProvider +import quickfix.Dictionary +import quickfix.Message +import quickfix.SLF4JLogFactory +import quickfix.Session +import quickfix.SessionID +import quickfix.SessionSettings +import quickfix.SessionState +import quickfix.SocketAcceptor +import quickfix.SocketInitiator +import quickfix.field.ApplVerID +import quickfix.field.MsgType +import quickfix.field.Text + +import java.awt.Color +import java.text.DecimalFormat +import java.text.DecimalFormatSymbols; +import java.util.logging.Logger +import java.util.regex.Matcher +import java.util.regex.Pattern; + +@CompileStatic +abstract class JrrQfHelper extends RstaScriptHelper { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public JrrQfDataHolder d; + public QfRstaRunnerWithStackTrace t; + + +// abstract void sendMsg(); + +// abstract void custom(); + +// abstract void Connect(); + + + void init2() { + t = runner as QfRstaRunnerWithStackTrace; + d = t.d; + } + + @Override + void init() { + super.init() + init2() + } + + boolean isNeedAddMsgToTable(Message msg, boolean isOutMsg) { + String msgType = msg.getHeader().getString(MsgType.FIELD) + boolean isUsefull = true + if (msgType == MsgType.HEARTBEAT) { + isUsefull = false + } + if (msgType == MsgType.TEST_REQUEST) { + isUsefull = false + } + if (d.autoFixSeqNum && msgType == MsgType.LOGOUT) { + if (msg.isSetField(Text.FIELD)) { + onLogoutWithText(msg, isOutMsg) + } + } + return isUsefull + } + + void onLogoutWithText(Message msg, boolean isOutMsg) { + String textLogout = msg.getString(Text.FIELD) + Matcher matcher = d.seqNumMismatch.matcher(textLogout) + if (matcher.matches()) { + int expected = matcher.group(1) as int + int my = matcher.group(2) as int; + fixSeqNum(expected, my, isOutMsg) + } + } + + void fixSeqNum(int expected, int my, boolean isOutMsg) { + log.info "expected = ${expected}, my = ${my}, isOutMsg = ${isOutMsg} " + if (!isOutMsg) { + int newExpected = expected + 1 + t.logs.append("setting newExpected = ${newExpected} \n") + t.modCount++ + t.showLogs() + d.qfSession.setNextSenderMsgSeqNum(newExpected) + d.qfSession.logon() + } + } + + + Properties parsePropsFromString(String s) { + Properties props4 = new Properties() + Properties props3 = new Properties() + StringReader stringReader = new StringReader(s) + props3.load(stringReader) + props3.entrySet().each { + String key = it.getKey() + String value = it.getValue() + key = key.trim() + value = value.trim() + props4.setProperty(key, value) + } + return props4; + } + + + DataDictionary getAppDd() { + if(d.qfSession==null){ + throw new Exception("Quick fix session was not inited") + } + DefaultDataDictionaryProvider dictionaryProvider = d.qfSession.getDataDictionaryProvider() as DefaultDataDictionaryProvider + Map map = JrrClassUtils.getFieldValue(dictionaryProvider, 'applicationDictionaries') as Map + Collection values = map.values() + assert values.size() == 1 + DataDictionary appDdd = values.iterator().next() as DataDictionary + return appDdd + + } + + String prepareMsg(String msg) { + + int i = msg.indexOf('' + d.humanSep + '10=') + if (i > 0) { + msg = msg.substring(0, i) + } + if (msg.endsWith('' + d.humanSep)) { + msg = msg.substring(0, msg.length() - 1) + } + + int j = msg.indexOf('' + d.humanSep + '35=') + if (j > 0) { + String msgForCheckSum = msg.substring(j) + Pattern pattern = Pattern.compile('\\|9=\\d+\\|') + Matcher matcher = pattern.matcher(msg) + if (matcher.find()) { + msg = matcher.replaceFirst('|9=' + msgForCheckSum.length() + d.humanSep) + } else { + if (msg.startsWith('8=')) { + throw new Exception("9 tag not found") + } + msg = '9=' + msgForCheckSum.length() + d.humanSep + msg + } + } + + + if (!msg.startsWith('8=')) { + String msg2 = '8=' + d.sessionID.getBeginString() + if (msg.charAt(0) == d.humanSep) { + msg = msg2 + msg + } else { + msg = msg2 + d.humanSep + msg + } + } + + + msg = msg.replace(d.humanSep, d.fixMsgNativeSep) + int checkSum = buildCheckSum(msg) + DecimalFormat decimalFormat = new DecimalFormat('000', DecimalFormatSymbols.getInstance(Locale.UK)) + String checkSumS = decimalFormat.format(checkSum) + msg += '' + d.fixMsgNativeSep + '10=' + checkSumS + d.fixMsgNativeSep + + return msg + } + + void sendMsgDirectly(Message message, int seqNum) { + JrrClassUtils.invokeJavaMethod(d.qfSession, 'sendRaw', message, seqNum) + } + + + void sendMsgDirectly2(String message) { + JrrClassUtils.invokeJavaMethod(d.qfSession, 'send', message) + } + + + + int buildCheckSum(String msg) { + int length = msg.length() + int checkSum = 0; + for (int i = 0; i < length; i++) { + char charAt = msg.charAt(i) + checkSum += charAt + } + checkSum = checkSum + 1 + checkSum = checkSum % 256 + return checkSum + } + + void initSession(Properties props3) { + d.lastMsgSend = new Date(); + d.modificationsCount++ + d.application = new JrrQfApplication(t) + t.statusField.setText("Staring") + t.statusField.setForeground(Color.YELLOW) + createSessionSettings() + d.prop2 = props3 + d.settings.set(d.prop2) + + createSessionId() + d.dictionary = new Dictionary(d.sessionID.toString(), d.prop2) + d.settings.set(d.sessionID, d.dictionary) +// SessionSettings settings = new SessionSettings(new ByteArrayInputStream(s.getBytes())); + createLogFactory() + createConnector() +// d.qfSession = Session.lookupSession(d.sessionID) + + Runnable r = { onTimeout() }; + if (d.timerPeriod == null) { + d.timerPeriod = new TimerPeriod(d.autoDisconnectTimeInSec * 1000, r) + d.timerPeriod.start() + } + d.timerPeriod.start() + updateLastRun() + } + + SessionID createSessionId() { + String beginString = d.settings.getString(SessionSettings.BEGINSTRING) + String senderCompID = d.settings.getString(SessionSettings.SENDERCOMPID) + String targetCompID = d.settings.getString(SessionSettings.TARGETCOMPID) + d.sessionID = new SessionID(beginString, senderCompID, targetCompID) + return d.sessionID + } + + void createSessionSettings() { + d.settings = new SessionSettings(); + } + +// DefaultSessionScheduleFactory createSessionScheduleFactory() { +// d.sessionScheduleFactory = new DefaultSessionScheduleFactory(); +// return d.sessionScheduleFactory; +// } + + Connector createConnector() { +// createSessionScheduleFactory() + createSessionFactory() + d.acceptor = d.prop2.containsKey('SocketAcceptPort') + log.info "acceptor = ${d.acceptor}" + if (d.acceptor) { + assert !properties.containsKey('SocketConnectPort') + d.connector = new SocketAcceptor(d.sessionFactory, d.settings, d.DEFAULT_QUEUE_CAPACITY) + } else { + assert !properties.containsKey('SocketAcceptPort') + d.connector = new SocketInitiator(d.sessionFactory, d.settings, d.DEFAULT_QUEUE_CAPACITY) + } + d.connector.start(); + return d.connector + } + + JrrQfSessionFactory createSessionFactory() { + d.sessionFactory = new JrrQfSessionFactory(d.application, d.storeFactory, d.logFactory, d.messageFactory, this) + return d.sessionFactory; + } + + SessionState getSessionState() { + SessionState sessionState = JrrClassUtils.getFieldValue(d.qfSession, 'state') as SessionState + return sessionState + } + + + void updateLastRun() { + d.lastMsgSend = new Date() + d.timerPeriod.getTimerImpl().setLastRun(d.lastMsgSend); + } + + + void setAutoDisconnectTimeInSecNew(long time) { + d.autoDisconnectTimeInSec = time + if (d.timerPeriod != null) { + d.timerPeriod.setPeriod(time * 1000) + } + } + + + void onTimeout() { + long disconeedNeededAt = d.lastMsgSend.getTime() + d.autoDisconnectTimeInSec * 1000L + boolean needStop = System.currentTimeMillis() > disconeedNeededAt + if (needStop) { + stopConnectionFromTimer() + String s = "${t.sdf.format(new Date())} : need disconnect at ${t.sdf.format(new Date(disconeedNeededAt))} " + log.info s + t.logs.append(s) + t.logs.append('\n') + t.modCount++ + t.showLogs() + d.timerPeriod.stop() + } else { + + } + + } + + void stopConnectionFromTimer() { + int modificationsCountRemember = d.modificationsCount; + synchronized (d.disconnectLock) { + d.disconnectLock.wait(d.autoDisconnectTimeInSec * 1000); + } + if (d.modificationsCount == modificationsCountRemember) { + log.info "stopping qf connection ${new Date()}" + t.stopCurrent() + } else { + log.info "count diff modificationsCountRemember = ${modificationsCountRemember}, now = ${d.modificationsCount}" + } + } + + + void createLogFactory() { + if (d.logFactory == null) { + d.logFactory = new SLF4JLogFactory(d.settings); + } + } + + + void dataDictionaryAllowAll(DataDictionary dd) { + dd.setCheckFieldsHaveValues(false) + dd.setCheckFieldsOutOfOrder(false) + dd.setCheckUnorderedGroupFields(false) + dd.setCheckUserDefinedFields(false) + } + + Session createSession(SessionID sessionID, SessionSettings sessionSettings) { + d.qfSession = d.sessionFactory.createSessionSuper(sessionID, sessionSettings) + configureSession(d.qfSession) + return d.qfSession; + } + + void configureSession(Session session) { + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfSessionFactory.groovy b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfSessionFactory.groovy new file mode 100644 index 00000000..31f311c0 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/JrrQfSessionFactory.groovy @@ -0,0 +1,37 @@ +package net.sf.jremoterun.utilities.nonjdk.quickfixsender + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import quickfix.Application +import quickfix.ConfigError +import quickfix.DefaultSessionFactory +import quickfix.LogFactory +import quickfix.MessageFactory +import quickfix.MessageStoreFactory +import quickfix.Session +import quickfix.SessionID +import quickfix.SessionSettings; + +import java.util.logging.Logger; + +@CompileStatic +class JrrQfSessionFactory extends DefaultSessionFactory{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public JrrQfHelper jrrQfHelper + + JrrQfSessionFactory(Application application, MessageStoreFactory messageStoreFactory, LogFactory logFactory, MessageFactory messageFactory, JrrQfHelper jrrQfHelper ) { + super(application, messageStoreFactory, logFactory, messageFactory) + this.jrrQfHelper = jrrQfHelper; + } + + @Override + Session create(SessionID sessionID, SessionSettings settings) throws ConfigError { + Session session=jrrQfHelper.createSession(sessionID, settings) + return session + } + + Session createSessionSuper(SessionID sessionID, SessionSettings settings) throws ConfigError { + return super.create(sessionID, settings) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfColumns.groovy b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfColumns.groovy new file mode 100644 index 00000000..9b8320a1 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfColumns.groovy @@ -0,0 +1,12 @@ +package net.sf.jremoterun.utilities.nonjdk.quickfixsender + +import groovy.transform.CompileStatic + +@CompileStatic +enum QfColumns { + + + date, inOut, marker, msg, + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfRstaRunnerWithStackTrace.groovy b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfRstaRunnerWithStackTrace.groovy new file mode 100644 index 00000000..cc0423ea --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfRstaRunnerWithStackTrace.groovy @@ -0,0 +1,424 @@ +package net.sf.jremoterun.utilities.nonjdk.quickfixsender + +import groovy.transform.CompileStatic +import net.infonode.docking.SplitWindow +import net.infonode.docking.TabWindow +import net.infonode.docking.View +import net.sf.jremoterun.JrrUtils; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.idwutils.IdwUtils +import net.sf.jremoterun.utilities.nonjdk.idwutils.TextAreaAndView +import net.sf.jremoterun.utilities.nonjdk.idwutils.ViewAndPanel +import net.sf.jremoterun.utilities.nonjdk.rstacore.RSyntaxTextAreaCodeAssistUndoFix +import net.sf.jremoterun.utilities.nonjdk.rstarunner.RstaRunnerWithStackTrace2 +import org.fife.ui.rsyntaxtextarea.SyntaxConstants +import org.fife.ui.rtextarea.RTextScrollPane +import quickfix.Message +import quickfix.field.MsgType + +import javax.swing.JButton +import javax.swing.JComboBox +import javax.swing.JList +import javax.swing.JOptionPane +import javax.swing.JPanel +import javax.swing.JPopupMenu +import javax.swing.JScrollPane +import javax.swing.JTable +import javax.swing.JTextField +import javax.swing.ScrollPaneConstants +import javax.swing.table.DefaultTableModel +import javax.swing.text.BadLocationException +import java.awt.BorderLayout +import java.awt.Color +import java.awt.FlowLayout +import java.awt.event.MouseAdapter +import java.awt.event.MouseEvent +import java.util.logging.Logger + +@CompileStatic +class QfRstaRunnerWithStackTrace extends RstaRunnerWithStackTrace2 { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + Vector columnNames = new Vector(QfColumns.values().toList().collect { it.name() }) + + + + JTextField statusField = new JTextField("Unknown") + // used ? + @Deprecated + JList list = new JList() + + public TextAreaAndView viewMsgToSendView = new TextAreaAndView("View msg "); + + + DefaultTableModel defaultTableModel = new DefaultTableModel() + JTable tableMsgs = new JTable(defaultTableModel) + JScrollPane tableMsgsScrollPane = new JScrollPane(tableMsgs) + View tableMsgsView = new View('messages', null, tableMsgsScrollPane); + File configDir; + JComboBox otherConfigInDir + JButton loadConfigButton = new JButton("Load send msg config") + SplitWindow splitPaneRight; + SplitWindow splitPaneQf; + QfRunnerType runnerType; + + JrrQfDataHolder d = new JrrQfDataHolder(this) + + + JrrQfHelper jrrQfHelperBefore; + JrrQfHelper jrrQfHelper; + + + public List technicalMsgTypesList = [ + MsgType.HEARTBEAT, MsgType.TEST_REQUEST, MsgType.RESEND_REQUEST, MsgType.SEQUENCE_RESET, + MsgType.LOGOUT, MsgType.LOGON, + ] + + // connect fields begin + JButton connectButton = new JButton("Connect") + File configConnectionDir; + JComboBox otherConfigConnectInDir + + JButton saveConnectConfigButton = new JButton("Save to file") + JButton loadConnectionConfigButton = new JButton("Load config") + + + public JPanel connectButtonsPanel = new JPanel(new FlowLayout()) + + + public static String groovySuffix = '.groovy' + + File fileWithConnectionConfig; + + RSyntaxTextAreaCodeAssistUndoFix connectRunnerTextArea = new RSyntaxTextAreaCodeAssistUndoFix() { + @Override + void appendFoldingMenu2(JPopupMenu popupMenu) { + appendFoldingMenu3(popupMenu); + } + }; + + + public JPanel connectPanel = new JPanel(new BorderLayout()) { + + @Override + public boolean requestFocusInWindow() { + return connectRunnerTextArea.requestFocusInWindow() + } + + } + + public ViewAndPanel viewConnectView = new ViewAndPanel('Connect', connectPanel); + + // connect fields end + + QfRstaRunnerWithStackTrace(File file, File connectFile) { + super(file) + + connectRunnerTextArea.scrollPane = new RTextScrollPane(connectRunnerTextArea, true); + connectRunnerTextArea.setTabSize(2); + connectRunnerTextArea.setCodeFoldingEnabled(true) + connectRunnerTextArea.addLangSupport() + connectRunnerTextArea.scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + connectRunnerTextArea.scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + connectRunnerTextArea.scrollPane.setIconRowHeaderEnabled(true); + fileWithConnectionConfig = connectFile; + this.configDir = file.getParentFile() + if (configDir != null) { + assert configDir.exists(); + List files = configDir.listFiles().toList().findAll { it.getName().endsWith(groovySuffix) } + List names = files.collect { it.getName().replace(groovySuffix, '') } + String[] namesArray = names.toArray(new String[0]) + otherConfigInDir = new JComboBox(namesArray); + otherConfigInDir.setSelectedItem(file.getName().replace(groovySuffix, '')) + loadConfigButton.addActionListener { + try { + loadConfig() + } catch (Throwable e2) { + log.info("failed load config ", e2) + showException(e2) + } + + } + panelButtons.add(otherConfigInDir) + panelButtons.add(loadConfigButton) + } + if (true) { + connectPanel.add(connectButtonsPanel, BorderLayout.NORTH) + connectPanel.add(connectRunnerTextArea.scrollPane, BorderLayout.CENTER) + configConnectionDir = connectFile.getParentFile(); + assert configConnectionDir.exists(); + List files = configConnectionDir.listFiles().toList().findAll { it.getName().endsWith(groovySuffix) } + List names = files.collect { it.getName().replace(groovySuffix, '') } + String[] namesArray = names.toArray(new String[0]) + otherConfigConnectInDir = new JComboBox(namesArray); + otherConfigConnectInDir.setSelectedItem(connectFile.getName().replace(groovySuffix, '')) + loadConnectionConfigButton.addActionListener { + try { + loadConnectionConfig() + } catch (Throwable e2) { + log.info("failed load connection config ", e2) + showException(e2) + } + + } + saveConnectConfigButton.addActionListener { + fileWithConnectionConfig.text = connectRunnerTextArea.getTextNormalized(); + } + connectRunnerTextArea.setText(fileWithConnectionConfig.text) + connectButtonsPanel.add(connectButton) + connectButtonsPanel.add(otherConfigConnectInDir) + connectButtonsPanel.add(loadConnectionConfigButton) + connectButtonsPanel.add(saveConnectConfigButton) + + } + defaultTableModel.setColumnIdentifiers(columnNames) + connectButton.addActionListener { + runnerType = QfRunnerType.connect; + prepareAndRun2(connectButton.getText()) + } +// sendMsgButton.addActionListener { +// prepareAndRun2("sendMsg") +// } +// customButton.addActionListener { +// prepareAndRun2("custom") +// } + + +// panelButtons.add(sendMsgButton) +// panelButtons.add(customButton) + statusField.setEditable(false) + panelButtons.add(statusField) +// msgToSendView.getTextArea().setText("|9=1|35=P|87=0|70=1") + viewMsgToSendView.textArea.setLineWrap(true) + +// rightPanel.addTab(msgToSendView.view) + tableMsgs.addMouseListener(new MouseAdapter() { + @Override + void mouseClicked(MouseEvent e) { + try { + showMsg(tableMsgs.getSelectedRow()) + } catch (Throwable e2) { + log.info("failed show selected msg ", e2) + showException(e2) + } + } + }); + viewMsgToSendView.getTextArea().setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML) + doLayoutQf() + } + + @Override + void onCloneActionListener() { + TabWindow parentIdwWindowSpecial = IdwUtils.getParentIdwWindowSpecial(runnerView.view.getWindowParent(), TabWindow) + RstaRunnerWithStackTrace2 newPanel = new QfRstaRunnerWithStackTrace(fileWithConfig, fileWithConnectionConfig) + parentIdwWindowSpecial.addTab(newPanel.getMainPanel3()) + } + + void doLayoutQf() { + TabWindow tabWindow2 = new TabWindow() + tabWindow2.addTab(viewMsgToSendView.view) + tabWindow2.addTab(viewConnectView.view) + splitPaneRight = new SplitWindow(false, 0.5f, rightPanel, tabWindow2) + splitPaneQf = new SplitWindow(false, 0.8f, runnerView.view, tableMsgsView) + mainPanel4 = new SplitWindow(true, 0.8f, splitPaneQf, splitPaneRight) + IdwUtils.setTitle(mainPanel4, 'QuickFix sender') + } + + void loadConfig() { + String ss = otherConfigInDir.getSelectedItem() + File f = configDir.child(ss + groovySuffix) + if (!f.exists()) { + JOptionPane.showMessageDialog(null, "File not exit : ${f}") + } else { + stopCurrent() + fileWithConfig = f + textAreaRunner.textArea.setText(f.text) + } + } + + void loadConnectionConfig() { + String ss = otherConfigConnectInDir.getSelectedItem() + File f = configConnectionDir.child(ss + groovySuffix) + if (!f.exists()) { + JOptionPane.showMessageDialog(null, "File connection not exit : ${f}") + } else { + stopCurrent() + fileWithConnectionConfig = f + connectRunnerTextArea.setText(f.text) + } + } + + + void stopCurrent() { + d.modificationsCount++; + if (d.connector != null) { + d.connector.stop(true) + } + } + + + void showMsg(int activeColumn) { + Vector row = defaultTableModel.getDataVector().get(activeColumn) + int i = columnNames.indexOf(QfColumns.msg.name()) + String msg = row.get(i); + showMsgAsXml(msg) + } + + + void showMsgAsXml(String msg) { + msg = msg.replace(d.humanSep, d.fixMsgNativeSep) + Message message = new Message(msg, jrrQfHelper.getAppDd()) + String asXml = message.toXML(jrrQfHelper.appDd) + asXml = removeXmlUseless(asXml) + viewMsgToSendView.getTextArea().setText(asXml) + } + + + static String removeXmlUseless(String asXml) { + + asXml = asXml.replace('', '') + asXml = asXml.replace('', '') + asXml = asXml.replace('', '') + return asXml + } + + @Override + void enableButtons() { + super.enableButtons() + connectButton.setEnabled(true) + +// sendMsgButton.setEnabled(true) +// customButton.setEnabled(true) + } + + @Override + void disableButtons() { + super.disableButtons() + connectButton.setEnabled(false) +// sendMsgButton.setEnabled(false) +// customButton.setEnabled(false) + + } + + @Override + public void prepareAndRun() { + textArea.removeAllLineHighlights(); + connectRunnerTextArea.removeAllLineHighlights() + } + + @Override + public void highLightLineAsError(int line) throws BadLocationException { + if (runnerType == QfRunnerType.connect) { + connectRunnerTextArea.addLineHighlight(line, Color.PINK); + } else { + //textArea.addLineHighlight(line, Color.PINK); + super.highLightLineAsError(line); + } + } + + @Override + String getTextToRun() { + if (runnerType == QfRunnerType.connect) { + return connectRunnerTextArea.getTextNormalized() + } + return super.getTextToRun() + } + + @Override + void codeStopped() { + super.codeStopped() + connectRunnerTextArea.removeAllLineHighlights() + runnerType = null + } + + @Override + protected void highLightCurrentExecutingLine(int line) throws BadLocationException { +// textArea.removeAllLineHighlights(); + connectRunnerTextArea.removeAllLineHighlights() + if (runnerType == QfRunnerType.connect) { + connectRunnerTextArea.addLineHighlight(line, Color.cyan); + } else { + //textArea.addLineHighlight(line, Color.cyan); + super.highLightCurrentExecutingLine(line) + } + } + + + @Override + void doLayoutCreateMainPanel() { + + } + + + void showException(Throwable e) { + e = JrrUtils.getRootException(e) + String excS = JrrUtils.exceptionToString(e) + viewMsgToSendView.getTextArea().setText(excS) + IdwUtils.setVisible(viewMsgToSendView.view) + } + + void addMessageToView(Message msg, boolean isOutMsg) { + try { + if (jrrQfHelper.isNeedAddMsgToTable(msg, isOutMsg)) { + Vector row = new Vector() + row.add sdf.format(new Date()) + String inOut = isOutMsg ? 'out' : 'in' + row.add inOut + row.add getMsgMarker(msg) + row.add msg.toString().replace(d.fixMsgNativeSep, d.humanSep); + defaultTableModel.addRow(row) + } + } catch (Throwable e) { + log.info("faild add msg ${isOutMsg} : ${msg} ", e) + showException(e) + } + } + + Character getMsgMarker(Message msg) { + Message.Header header = msg.getHeader() + if (header == null) { + return null + } + if (!header.isSetField(MsgType.FIELD)) { + return null + } + String msgType = header.getString(MsgType.FIELD) + Character res + if (technicalMsgTypesList.contains(msgType)) { + res = 'T'; + } else { + res = 'U' + } + + return res; + } + +// @Override +// Object runGroovyClass(Class scriptClass, Object param) throws Exception { +//// if (param == null) { +//// throw new IllegalStateException("Param is null. wrong button ?") +//// } +// super.runGroovyClass(scriptClass, param) +// String methodName = param; +// jrrQfHelperBefore = jrrQfHelper; +// jrrQfHelper = groovyScriptObject as JrrQfHelper +// jrrQfHelper.t = this +// jrrQfHelper.d = d +// //JrrClassUtils.invokeJavaMethod(groovyScriptObject, methodName) +// jrrQfHelper.run() +// return null +// } + + @Override + void preRunAfterScriptLoaded() { + super.preRunAfterScriptLoaded() + jrrQfHelperBefore = jrrQfHelper; + jrrQfHelper = groovyScriptObject as JrrQfHelper + jrrQfHelper.t = this + jrrQfHelper.d = d + } +// ---------------------------------------- + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfRunnerType.groovy b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfRunnerType.groovy new file mode 100644 index 00000000..c407f6aa --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/quickfixsender/QfRunnerType.groovy @@ -0,0 +1,12 @@ +package net.sf.jremoterun.utilities.nonjdk.quickfixsender + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +enum QfRunnerType { + std,connect, + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/redefineclass/RedefineClassI.groovy b/src/net/sf/jremoterun/utilities/nonjdk/redefineclass/RedefineClassI.groovy new file mode 100644 index 00000000..d4902a16 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/redefineclass/RedefineClassI.groovy @@ -0,0 +1,21 @@ +package net.sf.jremoterun.utilities.nonjdk.redefineclass + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import javax.management.ObjectName; +import java.util.logging.Logger; + +@CompileStatic +interface RedefineClassI { + + public ObjectName objectName = new ObjectName('iff:type=redefineClass') + public String thisClassCl = RedefineClassI.getName()+'.classloaderIff' + + void redefineClassOnly(String className,byte[] bytes,String classloaderId); + + void redefineClassOnly(String className,String classloaderId); + + void redefineClassAndAnonClasses( String className,String classloaderId); + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/redefineclass/RedefineClassImpl.groovy b/src/net/sf/jremoterun/utilities/nonjdk/redefineclass/RedefineClassImpl.groovy new file mode 100644 index 00000000..40cb7261 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/redefineclass/RedefineClassImpl.groovy @@ -0,0 +1,85 @@ +package net.sf.jremoterun.utilities.nonjdk.redefineclass + +import groovy.transform.CompileStatic +import net.sf.jremoterun.FindParentClassLoader +import net.sf.jremoterun.JrrUtils +import net.sf.jremoterun.SharedObjectsUtils +import net.sf.jremoterun.SimpleJvmTiAgent +import net.sf.jremoterun.utilities.DefaultObjectName; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.MBeanClient +import net.sf.jremoterun.utilities.MBeanFromJavaBean +import net.sf.jremoterun.utilities.MbeanConnectionCreator +import net.sf.jremoterun.utilities.OsInegrationClientI +import net.sf.jremoterun.utilities.javassist.JrrJavassistUtils + +import javax.management.MalformedObjectNameException +import javax.management.ObjectName +import java.lang.instrument.ClassDefinition; +import java.util.logging.Logger; + +@CompileStatic +class RedefineClassImpl implements RedefineClassI, DefaultObjectName { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public static ClassLoader defaultClassLoader = JrrClassUtils.getCurrentClassLoader(); + + public static RedefineClassImpl defaultInstance = new RedefineClassImpl(); + + static void registerMbeanIfNeeded() { + if(JrrUtils.findLocalMBeanServer().isRegistered(objectName)){ + log.info "already registered ${objectName}" + }else{ + registerMbean() + } + } + + static void registerMbean() { + MBeanFromJavaBean.registerMBean(new RedefineClassImpl()); + } + + + static void redefineClassOnlyS(Class clazz, byte[] bytes) { + final ClassDefinition classDefinition = new ClassDefinition(clazz, bytes); + ClassDefinition[] classDefinitions = [classDefinition]; + if (SimpleJvmTiAgent.instrumentation == null) { + throw new RuntimeException("JVM ti agent is not initialized"); + } + SimpleJvmTiAgent.instrumentation.redefineClasses(classDefinitions); + log.info "class redefined : ${clazz.getName()}" + } + + ClassLoader findClassloader(String classLoaderId) { + if (classLoaderId == thisClassCl) { + return defaultClassLoader + } + FindParentClassLoader loader = SharedObjectsUtils.getFindParentClassLoader() + return loader.findClassLoader(classLoaderId) + } + + @Override + void redefineClassOnly(String className, byte[] bytes, String classloaderId) { + Class clazz = findClassloader(classloaderId).loadClass(className); + redefineClassOnlyS(clazz, bytes) + } + + @Override + void redefineClassOnly(String className, String classloaderId) { + Class clazz = findClassloader(classloaderId).loadClass(className); + Class[] clll = [clazz] + SimpleJvmTiAgent.redefineClasses(clll); + log.info "class reloaded : ${className}" + } + + @Override + void redefineClassAndAnonClasses(String className, String classloaderId) { + Class clazz = findClassloader(classloaderId).loadClass(className); + JrrJavassistUtils.reloadClassAndAnonClasses(clazz); + } + + @Override + ObjectName getDefaultObjectName() throws MalformedObjectNameException { + return objectName; + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/serviceloader/IteratorServiceLoader.groovy b/src/net/sf/jremoterun/utilities/nonjdk/serviceloader/IteratorServiceLoader.groovy new file mode 100644 index 00000000..6ef482f9 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/serviceloader/IteratorServiceLoader.groovy @@ -0,0 +1,154 @@ +package net.sf.jremoterun.utilities.nonjdk.serviceloader + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class IteratorServiceLoader implements Iterator { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public ServiceLoader serviceLoader; + public Class service; + public ClassLoader serviceClassLoader; +// public Iterator originIterator; + public Enumeration configs; + public List servicesAsStr = []; + public Iterator servicesAsIter; + public ServiceLoaderStorage serviceLoaderFactory; + public LinkedHashMap providers = new LinkedHashMap<>(); + public volatile String next12 + + IteratorServiceLoader(ServiceLoader serviceLoader, Class service, ServiceLoaderStorage serviceLoaderFactory) { + this.serviceLoader = serviceLoader + this.serviceLoaderFactory = serviceLoaderFactory + this.service = service; + serviceClassLoader = JrrClassUtils.getFieldValue(serviceLoader, 'loader') as ClassLoader + String fullName = "META-INF/services/" + service.getName(); + if (serviceClassLoader == null) { + configs = ClassLoader.getSystemResources(fullName); + } else { + configs = serviceClassLoader.getResources(fullName); + } + configs.toList().each { + servicesAsStr.addAll(parseUrl(it)); + } + servicesAsStr = servicesAsStr.unique() + servicesAsStr.removeAll(serviceLoaderFactory.ignoreImpl2) + servicesAsIter = servicesAsStr.iterator() + } + + +// @Override +// boolean hasNext() { +// while (true) { +// boolean hasNext12 = servicesAsIter.hasNext() +// if (!hasNext12) { +// return false +// } +// String impl = servicesAsIter.next() +// if (isOkImpl(impl)) { +// next12 = impl +// return true +// } +// } +// } + +// boolean isOkImpl(String implClassName) { +// Collection skips = serviceLoaderFactory.skipImpl2 +// return !skips.contains(implClassName) +// } + @Override + boolean hasNext() { + return servicesAsIter.hasNext() + } + + @Override + Object next() { + String string1 = servicesAsIter.next() +// String string1 = next12 + return createService(string1) + } + + private Object createService(String cn) { + Class clazz = null; + try { + clazz = Class.forName(cn, false, serviceClassLoader); + } catch (ClassNotFoundException x) { + fail(service, "Provider " + cn + " not found"); + } + if (!service.isAssignableFrom(clazz)) { + fail(service, "Provider " + cn + " not a subtype"); + } + try { + Object p = service.cast(clazz.newInstance()); + providers.put(cn, p); + return p; + } catch (Throwable x) { + fail(service, "Provider " + cn + " could not be instantiated", x); + } + throw new Error(); // This cannot happen + } + + List parseUrl(URL u) throws ServiceConfigurationError { + InputStream inn = null; + BufferedReader r = null; + ArrayList names = new ArrayList<>(); + try { + inn = u.openStream(); + r = new BufferedReader(new InputStreamReader(inn, "utf-8")); + int lc = 1; + while ((lc = parseLine(service, u, r, lc, names)) >= 0); + } catch (IOException x) { + fail(service, "Error reading configuration file", x); + } finally { + try { + if (r != null) r.close(); + if (inn != null) inn.close(); + } catch (IOException y) { + fail(service, "Error closing configuration file", y); + } + } + return names; + } + + int parseLine(Class service, URL u, BufferedReader r, int lc, List names) + throws IOException, ServiceConfigurationError { + String ln = r.readLine(); + if (ln == null) { + return -1; + } + int ci = ln.indexOf('#'); + if (ci >= 0) ln = ln.substring(0, ci); + ln = ln.trim(); + int n = ln.length(); + if (n != 0) { + if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) + fail(service, u, lc, "Illegal configuration-file syntax: ${ln}"); + int cp = ln.codePointAt(0); + if (!Character.isJavaIdentifierStart(cp)) + fail(service, u, lc, "Illegal provider-class name: " + ln); + for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) { + cp = ln.codePointAt(i); +// if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) +// fail(service, u, lc, "Illegal provider-class name: " + ln); + } + if (!providers.containsKey(ln) && !names.contains(ln)) + names.add(ln); + } + return lc + 1; + } + + private static void fail(Class service, URL u, int line, String msg) throws ServiceConfigurationError { + fail(service, "${u}:${line}:${msg}"); + } + + + private static void fail(Class service, String msg) throws ServiceConfigurationError { + throw new ServiceConfigurationError(service.getName() + ": " + msg); + } + + private static void fail(Class service, String msg, Throwable cause) throws ServiceConfigurationError { + throw new ServiceConfigurationError(service.getName() + ": " + msg, cause); + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/serviceloader/ServiceLoaderFactory.groovy b/src/net/sf/jremoterun/utilities/nonjdk/serviceloader/ServiceLoaderFactory.groovy new file mode 100644 index 00000000..3f29317a --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/serviceloader/ServiceLoaderFactory.groovy @@ -0,0 +1,55 @@ +package net.sf.jremoterun.utilities.nonjdk.serviceloader + +import groovy.transform.CompileStatic +import net.sf.jremoterun.SharedObjectsUtils; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.javassist.codeinjector.InjectedCode +import net.sf.jremoterun.utilities.nonjdk.javassist.ClassRedefintions +import net.sf.jremoterun.utilities.nonjdk.problemchecker.JustStackTrace + +import java.lang.reflect.Field; +import java.util.logging.Logger; + +@CompileStatic +class ServiceLoaderFactory extends InjectedCode { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); +// public static ServiceLoaderFactory instance = new ServiceLoaderFactory(); + public static Field serviceClassField = JrrClassUtils.findField(ServiceLoader, 'service'); + public ServiceLoaderStorage loaderStorage; + + ServiceLoaderFactory(ServiceLoaderStorage loaderStorage) { + this.loaderStorage = loaderStorage + } + + + @Override + Object get(Object key) { + if (!(key instanceof ServiceLoader)) { + throw new RuntimeException("Strange key ${key.getClass()} : ${key}"); + } + ServiceLoader serviceLoader1 = key as ServiceLoader; + return getImpl(serviceLoader1) + } + + Iterator getImpl(ServiceLoader serviceLoader1) { + Class serviceClass = serviceClassField.get(serviceLoader1) + if (!loaderStorage.servicesTried.containsKey(serviceClass)) { + loaderStorage.servicesTried.put(serviceClass, new JustStackTrace()) + } + if (loaderStorage.customize.contains(serviceClass.getName())) { + return createIterator(serviceLoader1, serviceClass) + } + return null + } + + Iterator createIterator(ServiceLoader serviceLoader, Class service) { + return new IteratorServiceLoader(serviceLoader, service, loaderStorage); + } + + @Deprecated + static void init() { + ServiceLoaderStorage.init() + + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/serviceloader/ServiceLoaderStorage.groovy b/src/net/sf/jremoterun/utilities/nonjdk/serviceloader/ServiceLoaderStorage.groovy new file mode 100644 index 00000000..2c92ff96 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/serviceloader/ServiceLoaderStorage.groovy @@ -0,0 +1,58 @@ +package net.sf.jremoterun.utilities.nonjdk.serviceloader + +import groovy.transform.CompileStatic +import net.sf.jremoterun.SharedObjectsUtils; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.nonjdk.javassist.ClassRedefintions +import net.sf.jremoterun.utilities.nonjdk.problemchecker.JustStackTrace; + +import java.util.logging.Logger; + +@CompileStatic +class ServiceLoaderStorage { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public HashMap servicesTried = new HashMap<>() + public ServiceLoaderFactory factory1 = new ServiceLoaderFactory(this); + public HashSet customize = new HashSet<>(); + public HashSet ignoreImpl2 = new HashSet<>(); + + public static ServiceLoaderStorage instance = new ServiceLoaderStorage(); + public static volatile inited = false + public static String objectKey = "JrrServiceLoaderFactory" + + + ServiceLoaderStorage() { + addCustom(new ClRef('java.nio.file.spi.FileSystemProvider')) + addSkipImpl(new ClRef('org.apache.sshd.client.subsystem.sftp.SftpFileSystemProvider')) + addCustom(new ClRef('org.eclipse.jgit.transport.SshSessionFactory')) + addSkipImpl(new ClRef('org.eclipse.jgit.transport.sshd.SshdSessionFactory')) + } + + void addSkipImpl(ClRef clRef) { + ignoreImpl2.add(clRef.className) + } + +// HashSet receiveIgnoreImpls(){ +// return ignoreImpl2 +// } + + void addCustom(ClRef clRef) { + customize.add(clRef.className) + } + + /** + * for java9+ add : --add-reads=java.base=java.management + */ + static void init() { + if (inited) { + } else { + inited = true + SharedObjectsUtils.getGlobalMap().put(objectKey, instance.factory1); + ClassRedefintions.redefineServiceLoader(objectKey) + } + + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/shell/GroovySehllSshServiceSettings.groovy b/src/net/sf/jremoterun/utilities/nonjdk/shell/GroovySehllSshServiceSettings.groovy new file mode 100644 index 00000000..0d655b73 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/shell/GroovySehllSshServiceSettings.groovy @@ -0,0 +1,18 @@ +package net.sf.jremoterun.utilities.nonjdk.shell + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef; + +import java.util.logging.Logger; + +@CompileStatic +class GroovySehllSshServiceSettings { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static void setSshProps() { + System.setProperty(new ClRef('org.apache.sshd.common.io.IoServiceFactoryFactory').className, new ClRef('org.apache.sshd.netty.NettyIoServiceFactoryFactory').className) + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/shell/GroovyShellSshService.groovy b/src/net/sf/jremoterun/utilities/nonjdk/shell/GroovyShellSshService.groovy index 58b5009b..842f1456 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/shell/GroovyShellSshService.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/shell/GroovyShellSshService.groovy @@ -6,6 +6,8 @@ import java.util.logging.Logger; import groovy.transform.CompileStatic; + +// ssh -o "StrictHostKeyChecking=no" -p port host @CompileStatic class GroovyShellSshService extends GroovyShellService{ diff --git a/src/net/sf/jremoterun/utilities/nonjdk/shell/console/ConRunner3WithArgs.groovy b/src/net/sf/jremoterun/utilities/nonjdk/shell/console/ConRunner3WithArgs.groovy new file mode 100644 index 00000000..e25849fe --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/shell/console/ConRunner3WithArgs.groovy @@ -0,0 +1,46 @@ +package net.sf.jremoterun.utilities.nonjdk.shell.console + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams +import net.sf.jremoterun.utilities.groovystarter.ShortcutSelector +import net.sf.jremoterun.utilities.groovystarter.st.GroovyMethodRunnerParams2 +import net.sf.jremoterun.utilities.groovystarter.st.GroovyRunnerConfigurator +import net.sf.jremoterun.utilities.javassist.codeinjector.InjectedCode +import net.sf.jremoterun.utilities.nonjdk.consoleprograms.SetConsoleColoring +import net.sf.jremoterun.utilities.nonjdk.shell.GroovyShellConsole3 + +import java.nio.charset.Charset +import java.util.logging.Logger + +@CompileStatic +class ConRunner3WithArgs extends InjectedCode { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + @Override + Object get(Object key) { + Map shortcuts = key as Map + Map shortcuts2 = [:] + shortcuts.entrySet().each { + shortcuts2.put(it.key,new ShortcustHelperProp(it.value)) + } + SetConsoleColoring.setConsoleColoringNoRedirect() + GroovyShellConsole3 runner2 = new GroovyShellConsole3(){ + @Override + void displayWelcomeBanner2() { + super.displayWelcomeBanner2() + ShortcutSelector ss = new ShortcutSelector(shortcuts) + ss.printHelp() + } + } + File currentDir = new File(".").absoluteFile.canonicalFile + runner2.binding.setVariable('s', shortcuts2) + runner2.binding.setVariable('currentDir', currentDir) + runner2.binding.setVariable('gmrp', GroovyMethodRunnerParams.gmrp) + runner2.binding.setVariable('gmrp2', GroovyMethodRunnerParams2.gmrp2) + runner2.runConsole() + Charset.defaultCharset() + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/shell/console/GroovyShellRunnerFromConsole.groovy b/src/net/sf/jremoterun/utilities/nonjdk/shell/console/GroovyShellRunnerFromConsole.groovy index 986b2c84..0d714f9c 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/shell/console/GroovyShellRunnerFromConsole.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/shell/console/GroovyShellRunnerFromConsole.groovy @@ -25,10 +25,10 @@ class GroovyShellRunnerFromConsole extends GroovyRunnerConfigurator implements C @Override void doConfig() { AddFilesToUrlClassLoaderGroovy adder = gmrp.addFilesToClassLoader - addClassthapAndRun(adder) + addClassPathAndRun(adder) } - void addClassthapAndRun(AddFilesToUrlClassLoaderGroovy adder) { + void addClassPathAndRun(AddFilesToUrlClassLoaderGroovy adder) { adder.addAll mavenIds RunnableFactory.runRunner cnr } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/shell/console/GroovyShellRunnerFromConsoleWithMap.groovy b/src/net/sf/jremoterun/utilities/nonjdk/shell/console/GroovyShellRunnerFromConsoleWithMap.groovy new file mode 100644 index 00000000..c91565d4 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/shell/console/GroovyShellRunnerFromConsoleWithMap.groovy @@ -0,0 +1,41 @@ +package net.sf.jremoterun.utilities.nonjdk.shell.console + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.AddFilesToUrlClassLoaderGroovy +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.groovystarter.ClassNameSynonym +import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams +import net.sf.jremoterun.utilities.groovystarter.runners.RunnableFactory +import net.sf.jremoterun.utilities.groovystarter.runners.RunnableWithParamsFactory +import net.sf.jremoterun.utilities.groovystarter.st.GroovyRunnerConfigurator +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.GroovyMavenIds +import net.sf.jremoterun.utilities.nonjdk.classpath.refs.LatestMavenIds + +import java.util.logging.Logger + +@CompileStatic +class GroovyShellRunnerFromConsoleWithMap implements Runnable{ + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static ClRef cnr2 = new ClRef("net.sf.jremoterun.utilities.nonjdk.shell.console.ConRunner3WithArgs") + + public Map shortcuts + + GroovyShellRunnerFromConsoleWithMap(Map shortcuts) { + this.shortcuts = shortcuts + } + + @Override + void run() { + AddFilesToUrlClassLoaderGroovy adder = GroovyMethodRunnerParams.gmrp.addFilesToClassLoader + addClassPathAndRun(adder) + } + + void addClassPathAndRun(AddFilesToUrlClassLoaderGroovy adder) { + adder.addAll GroovyShellRunnerFromConsole.mavenIds + RunnableWithParamsFactory.fromClass4(cnr2, shortcuts) + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/shell/console/ShortcustHelperProp.groovy b/src/net/sf/jremoterun/utilities/nonjdk/shell/console/ShortcustHelperProp.groovy new file mode 100644 index 00000000..ffb3d5dc --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/shell/console/ShortcustHelperProp.groovy @@ -0,0 +1,42 @@ +package net.sf.jremoterun.utilities.nonjdk.shell.console + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.groovystarter.ClassNameSynonym +import net.sf.jremoterun.utilities.groovystarter.GroovyMethodRunnerParams +import net.sf.jremoterun.utilities.groovystarter.LoadScriptFromFileUtils +import net.sf.jremoterun.utilities.groovystarter.runners.ClRefRef +import org.codehaus.groovy.runtime.MethodClosure; + +import java.util.logging.Logger; + +@CompileStatic +class ShortcustHelperProp { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + private Object value + private Object value2 + + ShortcustHelperProp(Object value) { + this.value = value + } + + + Object getO() { + if(value2!=null){ + return value2 + } + if (value instanceof ClRefRef) { + value2 = value.getClRef().loadClass2().newInstance() + } else if (value instanceof Class) { + value2 = value.newInstance() + } else if (value instanceof MethodClosure) { + value2 = value + }else { + value2 = value + } +// log.info "resolve value2 : ${value2} ${value2.getClass()}" + return value2 + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/shell/core/GroovyShellRunner2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/shell/core/GroovyShellRunner2.groovy index 21470a9b..23c3bc21 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/shell/core/GroovyShellRunner2.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/shell/core/GroovyShellRunner2.groovy @@ -78,7 +78,7 @@ abstract class GroovyShellRunner2 { JrrClassUtils.setFieldValue(Preferences, "STORE", overridenProps) overridenProps.props.put(PackageHelperImpl.IMPORT_COMPLETION_PREFERENCE_KEY, Boolean.TRUE.toString()) log.info "initialiing packages .." - initializePackages = PackageHelperImpl.initializePackages(classLoaderDefault) + //initializePackages = PackageHelperImpl.initializePackages(classLoaderDefault) log.info "packages inited" } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/ConnectionState.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/ConnectionState.groovy new file mode 100644 index 00000000..3341c80b --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/ConnectionState.groovy @@ -0,0 +1,17 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import groovy.transform.CompileStatic; + + +@CompileStatic +enum ConnectionState { + + notInited, + inProgressNoConnected, + disconnected, + inProgressConnected, + AuthPassed, + AuthFailed, + ConnectionFailed, + +} \ No newline at end of file diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/FilePermissions.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/FilePermissions.groovy new file mode 100644 index 00000000..228e1afe --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/FilePermissions.groovy @@ -0,0 +1,48 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +enum FilePermissions { + + read(4), + write(2), + execute(1), + ; + + + public byte offset; + + FilePermissions(int offset) { + this.offset = (byte) offset + } + + List> decodeAll(int permission){ + int base1 = permission & 7; + int base2= Integer.parseInt('70',8); + int base3= Integer.parseInt('700',8); + int permission1 = permission&base1 + int permission2 = permission&base2 + int permission3 = permission&base3 + return null; + } + + static byte getPermission(int permission, byte offset){ + + } + + static List decode(byte permission){ + return values().toList().findAll{it.offset && permission >0} + } + + byte incode(Collection permissions){ + Collection permissions1 = permissions.unique() + byte result = 0; + permissions1.each { + result+=it.offset + } + return result; + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/FoundManyException.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/FoundManyException.groovy new file mode 100644 index 00000000..c8445aba --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/FoundManyException.groovy @@ -0,0 +1,18 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class FoundManyException extends Exception{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + FoundManyException(String var1) { + super(var1) + } + + FoundManyException(String var1, Throwable var2) { + super(var1, var2) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JcraftConnectopnOpener.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JcraftConnectopnOpener.groovy index 6bb94904..1dd09f86 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JcraftConnectopnOpener.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JcraftConnectopnOpener.groovy @@ -13,52 +13,79 @@ class JcraftConnectopnOpener implements UserInfo { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static int defaultLogonTimeout = 10000; + public int logonTimeoutInMs = defaultLogonTimeout; + + /** + * -1 : mean disable + */ + public static int defaultAfterLogonTimeout = -1 + SshConSet2 conSet2 - Session session + JrrJschSession session JSch jsch; - void init(){ - JSch jsch2 = new JSch(); + boolean showMessageProp = true + + String lastMessage; + + void init() { + JrrJSch jsch2 = new JrrJSch(); configure(jsch2); } - void configure(JSch jsch){ + void configure(JSch jsch) { this.jsch = jsch defaultAddKnownHosts() defaultPrivateKey() session = createSession(); - if(conSet2.password!=null){ - session.password = conSet2.password + if (conSet2.password != null) { + session.setPassword( conSet2.password) session.setUserInfo(this) } + if(conSet2.user!=null){ + if (session instanceof JrrJschSession) { + JrrJschSession session7= (JrrJschSession) session; + session7.setUserName(conSet2.user) + + } + + } final java.util.Properties config = new java.util.Properties(); config.put("compression.s2c", "zlib,none"); config.put("compression.c2s", "zlib,none"); configureSession(session, config); session.connect(); - session.setTimeout(0); + if (defaultAfterLogonTimeout >= 0) { + session.setTimeout(defaultAfterLogonTimeout); + } } void configureSession(Session session, Properties config) { session.setConfig(config); - session.setTimeout(5000); + if(logonTimeoutInMs>=0) { + session.setTimeout(logonTimeoutInMs); + } } - Session createSession(){ - Session session2 = jsch.getSession(conSet2.user, conSet2.host, conSet2.port); + JrrJschSession createSession() { + assert conSet2.host!=null + //Session session2 = jsch.getSession(conSet2.user, conSet2.host, conSet2.port); + JrrJschSession session2 = new JrrJschSession(jsch,conSet2.user, conSet2.host, conSet2.port); + session2.jcraftConnectopnOpener = this return session2 } - void defaultAddKnownHosts(){ - if (conSet2.knownHosts!=null) { + void defaultAddKnownHosts() { + if (conSet2.knownHosts != null) { jsch.setKnownHosts(conSet2.knownHosts.absolutePath); } } - void defaultPrivateKey(){ - if (conSet2.sshKey!=null) { + void defaultPrivateKey() { + if (conSet2.sshKey != null) { jsch.addIdentity(conSet2.sshKey.absolutePath); } } @@ -90,6 +117,9 @@ class JcraftConnectopnOpener implements UserInfo { @Override void showMessage(String message) { - log.info "${message}" + if (conSet2.showMessage) { + log.info "${message}" + } + lastMessage = message } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJSch.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJSch.groovy new file mode 100644 index 00000000..d3a8d057 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJSch.groovy @@ -0,0 +1,37 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import com.jcraft.jsch.JSch +import com.jcraft.jsch.JSchException +import com.jcraft.jsch.JrrKnowHostOriginal +import com.jcraft.jsch.KnownHosts +import com.jcraft.jsch.Session +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class JrrJSch extends JSch{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + JrrJSch() { + JrrClassUtils.setFieldValue(this,'known_hosts',new JrrJrrKnowHost(this)) + } + + @Override + Session getSession(String username, String host, int port) throws JSchException { + assert host!=null + JrrJschSession s = new JrrJschSession(this, username, host, port); + return s + } + + @Override + protected void addSession(Session session) { + log.info "connection established : ${session.getHost()} ${session.getPort()}" + JrrJschSession s = session as JrrJschSession + s.onConnected(); + super.addSession(session) + } + + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJrrKnowHost.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJrrKnowHost.groovy new file mode 100644 index 00000000..53ed38ca --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJrrKnowHost.groovy @@ -0,0 +1,26 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import com.jcraft.jsch.HostCheckResultEnum +import com.jcraft.jsch.JSch +import com.jcraft.jsch.JrrKnowHostOriginal +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class JrrJrrKnowHost extends JrrKnowHostOriginal{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + JrrJrrKnowHost(JSch jsch) { + super(jsch) + } + + + @Override + int check(String host, byte[] key) { + int result = super.check(host, key) + HostCheckResultEnum resultEnum = HostCheckResultEnum.statusMap.get(result) + log.info "${host} host key result ${resultEnum}" + return result + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJschIO.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJschIO.groovy new file mode 100644 index 00000000..caf88104 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJschIO.groovy @@ -0,0 +1,31 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import com.jcraft.jsch.Channel +import com.jcraft.jsch.IO +import com.jcraft.jsch.JrrJschSessionOriginal +import com.jcraft.jsch.JrrJschStaticUtils +import com.jcraft.jsch.JschIOOriginal +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class JrrJschIO extends JschIOOriginal{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + JrrJschIO() { + } + + static JrrJschIO createJrrJschIOAndSet(Channel channel){ + JrrJschIO jrrJschIO = new JrrJschIO() + JrrJschStaticUtils.setJschIo(channel,jrrJschIO) + return jrrJschIO + } + + @Override + void out_close() { + super.out_close() + log.info "out close" + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJschSession.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJschSession.groovy new file mode 100644 index 00000000..05bb6ee5 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/JrrJschSession.groovy @@ -0,0 +1,180 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import com.jcraft.jsch.Channel +import com.jcraft.jsch.JSch +import com.jcraft.jsch.JSchException +import com.jcraft.jsch.JrrJschSessionOriginal +import com.jcraft.jsch.JrrJschStaticUtils +import com.jcraft.jsch.JrrSchSessionLog +import com.jcraft.jsch.UserInfo +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.auth.AuthState +import net.sf.jremoterun.utilities.nonjdk.sshsup.channels.JrrJschSessionMethods +import net.sf.jremoterun.utilities.nonjdk.sshsup.channels.JschChannelType + +import java.text.SimpleDateFormat; +import java.util.logging.Logger; + +@CompileStatic +class JrrJschSession extends JrrJschSessionOriginal { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + //JrrJschIO jrrJschIO = JrrJschIO.createJrrJschIOAndSet(this) + + public volatile static boolean logSessionSettingsDefault = false + public volatile boolean logSessionSettings = logSessionSettingsDefault; + public static int connectionTimeoutOverrideDefault = -1;; + public int connectionTimeoutOverride = connectionTimeoutOverrideDefault; + public ConnectionState connectionState = ConnectionState.notInited; + + public JcraftConnectopnOpener jcraftConnectopnOpener + + public volatile static JrrSchSessionLog jrrSchSessionLogDefault = new JrrSchSessionLog(); + public volatile JrrSchSessionLog jrrSchSessionLog = jrrSchSessionLogDefault; + + public List auths = [] + public Throwable exceptionFromConnect; + public final Date startDate = new Date(); + + JrrJschSession(JSch jsch, String username, String host, int port) throws JSchException { + super(jsch, username, host, port) + } + + + String getConnectionStateHuman(){ + if(connectionState == ConnectionState.AuthPassed){ + return 'auth passed' + } + if(connectionState == ConnectionState.notInited){ + return 'not inited' + } + if(connectionState == ConnectionState.inProgressConnected){ + if(auths.size()==0){ + return "inProgressConnected, auth state nothing" + } + return "inProgressConnected, auth state : ${auths.last()}" + } + return connectionState.toString(); + } + + @Override + String getConfig(String key) { + String result = super.getConfig(key) + if(logSessionSettings) { + log.info "resolved session config : ${key} = ${result}" + } + return result; + } + + @Override + Channel openChannel(String type) throws JSchException { + if (!isConnected()) { + throw new JSchException("session is down"); + } + + JschChannelType typeE = JschChannelType.allMap.get(type) + log.info "openning channel type = ${type}, ${typeE}" + jrrSchSessionLog.logMsg "opening channel : ${type}"; + if (typeE == null) { + return openChannel3(type) + } + return openChannel2(typeE) +// Channel channel=Channel.getChannel(type); +// addChannel(channel); +// channel.init(); +// if(channel instanceof ChannelSession){ +// applyConfigChannel((ChannelSession)channel); +// } +// return channel; + + } + + Channel openChannel2(JschChannelType type) throws JSchException { + Channel channel = type.clazz.newInstance(); +// if (channel instanceof JrrJschSessionMethods) { +// JrrJschSessionMethods sessionMethods = (JrrJschSessionMethods) channel; +// sessionMethods.setJrrJschSession(this) +// } + addChannel(channel); + JrrJschStaticUtils.callChannelInit(channel) + if (JrrJschStaticUtils.isChannelSession(channel)) { + JrrClassUtils.invokeJavaMethod(this, 'applyConfigChannel', channel) + //applyConfigChannel((ChannelSession)channel); + } + return channel; + } + + @Override + void disconnect() { + SimpleDateFormat sdf = new SimpleDateFormat('dd HH:mm'); + jrrSchSessionLog.logMsg("disconnect ${sdf.format(new Date())}"); + super.disconnect() + connectionState = ConnectionState.disconnected; + log.info "disconnected ${getHost()}" + } + + Channel openChannel3(String type) throws JSchException { + return super.openChannel(type) + } + + + + @Override + void connect(int connectTimeout) throws JSchException { + if(connectionTimeoutOverride>=0){ + connectTimeout = connectionTimeoutOverride; + } + + jrrSchSessionLog.logMsg "connecting with timeout ${connectTimeout} ms .."; +// if(jcraftConnectopnOpener.conSet2.user!=null){ +// setUserName(jcraftConnectopnOpener.conSet2.user) +// } +// if(jcraftConnectopnOpener.conSet2.password!=null){ +// setPassword(jcraftConnectopnOpener.conSet2.password) +// } + UserInfo userInfo1 = getUserInfo(); + if(userInfo1!=null){ + if (userInfo1 instanceof UserInfoJrr) { + + }else{ + UserInfoJrr u = new UserInfoJrr(userInfo1,this) + setUserInfo(u) + } + } + try { + super.connect(connectTimeout) + }catch(Throwable e) { + exceptionFromConnect = e + jrrSchSessionLog.logMsg "exception : ${e}"; + throw e + }finally { + if (isAuthed2()) { + connectionState = connectionState.AuthPassed; + } else { + if (connectionState == connectionState.inProgressConnected) { + connectionState = connectionState.AuthFailed; + } else { + connectionState == connectionState.ConnectionFailed + } + + } + } + } + + boolean isAuthed2(){ + return (Boolean)JrrClassUtils.getFieldValue(this,'isAuthed'); + } + + void onConnected() { + connectionState = connectionState.inProgressConnected; + long diff = System.currentTimeMillis() - startDate.getTime() + diff = (long)(diff/1000) + jrrSchSessionLog.logMsg "connected within ${diff}s"; + } + + String getPassword2() { + return (String)JrrClassUtils.getFieldValue(this,'password') + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/MavericSshSup.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/MavericSshSup.groovy index fa6bf0b9..e72e5f1d 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/MavericSshSup.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/MavericSshSup.groovy @@ -1,9 +1,17 @@ package net.sf.jremoterun.utilities.nonjdk.sshsup - +import com.sshtools.net.SocketTransport +import com.sshtools.ssh.HostKeyVerification +import com.sshtools.ssh.SshClient +import com.sshtools.ssh.SshConnector +import com.sshtools.ssh.SshContext +import com.sshtools.ssh.SshException import com.sshtools.ssh.components.ComponentManager +import com.sshtools.ssh.components.SshPublicKey import com.sshtools.ssh.components.jce.JCEComponentManager; -import net.sf.jremoterun.utilities.JrrClassUtils; +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.util.logging.Level; import java.util.logging.Logger; import groovy.transform.CompileStatic; @@ -14,10 +22,12 @@ class MavericSshSup { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); - static void addSupportedProtocolsForSsh(){ - JCEComponentManager instance = (JCEComponentManager)ComponentManager.getInstance() - instance.installCBCCiphers( instance.supportedSsh2CiphersCS()) - instance.installCBCCiphers( instance.supportedSsh2CiphersSC()) + static void addSupportedProtocolsForSsh() { + JCEComponentManager instance = (JCEComponentManager) ComponentManager.getInstance() + instance.installCBCCiphers(instance.supportedSsh2CiphersCS()) + instance.installCBCCiphers(instance.supportedSsh2CiphersSC()) } + + } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SftpUtils.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SftpUtils.groovy index 473232db..2ff141aa 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SftpUtils.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SftpUtils.groovy @@ -1,10 +1,12 @@ package net.sf.jremoterun.utilities.nonjdk.sshsup import com.jcraft.jsch.ChannelSftp +import com.jcraft.jsch.SftpATTRS import com.sshtools.sftp.SftpClient import com.sshtools.ssh2.Ssh2Client import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.channels.JrrChannelSftp import java.util.logging.Logger @@ -12,50 +14,258 @@ import java.util.logging.Logger * TODO during download or upload dir : Support to filter out unwanted content. Support to download only if newer. */ @CompileStatic -class SftpUtils implements Closeable{ +class SftpUtils implements Closeable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); // SshConSet sshConSet - ChannelSftp sftp; + JrrChannelSftp sftp; public Ssh2Client ssh3 SftpClient sftp2 @Override void close() throws IOException { - if(sftp!=null) { + if (sftp != null) { sftp.disconnect() } - if(sftp2!=null) { + if (sftp2 != null) { sftp2.exit() } - if(ssh3!=null) { + if (ssh3 != null) { ssh3.disconnect() } } String findRemoteFile(String remoteFile) { - def tokenize = remoteFile.tokenize('/') + try { + return findRemoteFileImpl(remoteFile) + } catch (Exception e) { + log.info "failed find remote file : ${remoteFile}" + throw e + } + } + + void cd(String remotePath) { + try { + sftp.cd(remotePath) + } catch (Exception e) { + log.info "failed cd to : ${remotePath}" + throw e + } + } + + InputStream get(String remotePath) { + try { + return sftp.get(remotePath) + } catch (Exception e) { + log.info "failed get : ${remotePath}" + throw e + } + } + + void getFile(String remotePath, File dest) { + get(remotePath, dest) + } + + void get(String remotePath, File dest) { + try { + sftp.get(remotePath, dest.getAbsolutePath()) + } catch (Exception e) { + log.info "failed get : ${remotePath}" + throw e + } + } + + void putFile(File src, String remotePath) { + put(src, remotePath) + } + + /** + * sample permission : 755 - write user only, other can read only + */ + void setPermissions(String remotePath, int permissions){ + String permS = permissions; + sftp.chmod(Integer.parseInt(permS,8),remotePath) + } + + void setPermissions2(String remotePath, int permissions){ + String permS = permissions; + sftp2.chmod(Integer.parseInt(permS,8),remotePath) + } + + void put(File src, String remotePath) { + try { + sftp.put(src.getAbsolutePath(), remotePath) + } catch (Exception e) { + log.info "failed put ${src} to ${remotePath}" + throw e + } + } + + + String findRemoteFile2(String remoteFile) { + return findRemoteFile2(remoteFile, 1) + } + + String findRemoteFile2(String remoteFile, int maxFoundCount) { + List res = findRemoteFiles2(remoteFile, maxFoundCount) + int size = res.size() + if (size == 0) { + throw new Exception("not found : ${remoteFile}") + } + if (size > 1) { + throw new Exception("found many : ${res.sort()}") + } + return res[0] + } + + List findRemoteFiles2(String remoteFile, int maxFoundCount) { + remoteFile = remoteFile.replace('//', '/') + remoteFile = remoteFile.replace('//', '/') + List subPaths = remoteFile.tokenize('/') + List sub2 = new ArrayList<>(subPaths) + String cur = sub2.remove(0) + return handleSubPath('', cur, sub2, maxFoundCount, true, false) + } + + + boolean changeDir(String pathParent, boolean throwExc) { + try { + if (pathParent.length() == 0) { + sftp.cd('/') + } else { + sftp.cd(pathParent) + } + return true + } catch (Exception e) { + log.info "failed cd to : ${pathParent} ${e}" + if (throwExc) { + throw e + } + return false + } + } + + List handleSubPath(final String pathParent, String el, List subPaths, int maxFoundCount, boolean throwExc, boolean forceCd) { + if (!el.contains("*")) { + String s = pathParent + '/' + el; + if (forceCd) { + if (!changeDir(s, throwExc)) { + return [] + } + } + if (subPaths.size() == 0) { + return [s] + } + List sub2 = new ArrayList<>(subPaths) + String cur = sub2.remove(0) + return handleSubPath(s, cur, sub2, maxFoundCount, throwExc, forceCd) + } + if (!changeDir(pathParent, throwExc)) { + return [] + } + Collection result = handleElementAstrix(el, pathParent) + int size = result.size() + if (size == 0) { + if (throwExc) { + throw new Exception("no matches in ${pathParent} for ${el}") + } + return [] + } + List fileNames = result.collect { it.getFilename() }.sort() + log.info "result many : ${}" + + if (size == 1) { + String s = pathParent + '/' + fileNames[0] + if (subPaths.size() == 0) { + return [s] + } + List sub2 = new ArrayList<>(subPaths) + String cur = sub2.remove(0) + return handleSubPath(s, cur, sub2, maxFoundCount, throwExc, forceCd) + } + if (size > maxFoundCount) { + throw new FoundManyException("Found many matches in ${pathParent} candidates : ${fileNames} , max allowed : ${maxFoundCount}") + } + if (subPaths.size() == 0) { + return result.collect { pathParent + '/' + it } + } + List sub2 = new ArrayList<>(subPaths) + String cur = sub2.remove(0) + int newMaxFoundCount = maxFoundCount - size + List result2 = [] + result.each { + SftpATTRS attrs = it.getAttrs() + if (attrs.isDir()) { + String s = pathParent + '/' + it.getFilename(); + + log.info "going to ${s}" + result2.addAll(handleSubPath(s, cur, sub2, newMaxFoundCount, false, true)) + } else { + log.info "not a dir : ${it.getFilename()} from ${pathParent}" + } + } + + if (result2.size() == 0 && throwExc) { + throw new Exception("no matches in ${pathParent} for ${el}") + } + return result2; + } + + Collection handleElementAstrix(String el, final String path) { + try { + Collection ls = sftp.ls(el) as Collection + switch (ls.size()) { + case 0: + return [] +// case 1: +// return [ls.first().getFilename()] +// break + default: + return ls; + //throw new Exception("Many files for : ${path}/${el} : ${ls.collect { it.getFilename() }.sort()})") + } + } catch (Exception e) { + log.info "failed list in : ${path} for ${el}" + throw e + } +// } +// return [path + el] + + } + + String findRemoteFileImpl(String remoteFile) { + List tokenize = remoteFile.tokenize('/') String path = remoteFile.startsWith('/') ? '/' : '' boolean first = true tokenize.each { String el -> if (el.contains("*")) { - sftp.cd(path) - Collection ls = sftp.ls(el) as Collection - switch (ls.size()) { - case 0: - throw new Exception("Not found : ${path}/${el}") - case 1: - if (first) { - first = false - } else { - path += '/' - } - path += ls.first().filename - break - default: - throw new Exception("Many files for : ${path}/${el} : ${ls.collect { it.filename }.sort()})") + try { + sftp.cd(path) + } catch (Exception e) { + log.info "failed cd to : ${path}" + throw e + } + try { + Collection ls = sftp.ls(el) as Collection + switch (ls.size()) { + case 0: + throw new Exception("Not found : ${path}/${el}") + case 1: + if (first) { + first = false + } else { + path += '/' + } + path += ls.first().filename + break + default: + throw new Exception("Many files for : ${path}/${el} : ${ls.collect { it.filename }.sort()})") + } + } catch (Exception e) { + log.info "failed list in : ${path} for ${el}" + throw e } } else { if (first) { @@ -72,5 +282,4 @@ class SftpUtils implements Closeable{ return path } - } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshBadExitCodeException.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshBadExitCodeException.groovy new file mode 100644 index 00000000..7c520ac3 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshBadExitCodeException.groovy @@ -0,0 +1,14 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class SshBadExitCodeException extends Exception{ + + + SshBadExitCodeException(String var1) { + super(var1) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshCommandExec.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshCommandExec.groovy new file mode 100644 index 00000000..1954bf46 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshCommandExec.groovy @@ -0,0 +1,125 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.channels.JrrChannelExec +import org.apache.commons.io.output.TeeOutputStream +import org.apache.commons.lang.StringUtils; + +import java.util.logging.Logger; + +@CompileStatic +class SshCommandExec { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static int maxDataLength = 1024; + + public JrrChannelExec execChannel; + public String cmd; + public ByteArrayOutputStream err2 = new ByteArrayOutputStream() + public ByteArrayOutputStream out1 = new ByteArrayOutputStream() + public ByteArrayOutputStream err1 = new ByteArrayOutputStream() + public final Object lock = new Object(); + + public String err2S + public String outS + public String err1S; + + SshCommandExec(JrrChannelExec channelExec, String cmd) { + this.execChannel = channelExec + this.cmd = cmd + } + + void onFinish() { + + synchronized (lock) { + lock.notifyAll() + } + } + + + void printExitData() { + + if (true) { + outS = out1.toString().trim() + if (StringUtils.isEmpty(outS)) { + outS = null + } else { + if (outS.length() > maxDataLength) { + outS = outS.substring(outS.length() - maxDataLength); + } + log.info "out = ${outS}" + } + } + + if (true) { + err1S = err1.toString().trim() + if (StringUtils.isEmpty(err1S)) { + err1S = null + } else { + if (err1S.length() > maxDataLength) { + err1S = err1S.substring(err1S.length() - maxDataLength); + } + log.info "err1 = ${err1S}" + } + } + + err2S = err2.toString().trim() + if (StringUtils.isEmpty(err2S)) { + err2S = null + } else { + if (err2S.length() > maxDataLength) { + err2S = err1S.substring(err2S.length() - maxDataLength); + } + log.info "err2 = ${err2S}" + } + + + log.info "exit code : ${execChannel.getExitStatus()}" + } + + + void setStreamsWithParallelLogToSysout() { + TeeOutputStream err5 = new TeeOutputStream(System.out, err2); + TeeOutputStream out5 = new TeeOutputStream(System.out, out1); + TeeOutputStream extOut5 = new TeeOutputStream(System.out, err1); + + + execChannel.setErrStream(err5, true) + execChannel.setOutputStream(out5, true) + execChannel.setExtOutputStream(extOut5, true) + } + + void startAndWait() { + startAndWait(0) + } + + void startAndWait(long waitTimeOut) { + synchronized (lock) { + start(); + lock.wait(waitTimeOut) + } + printExitData(); + checkExitCodeAndThrowExc() + log.info "finished2" + } + + void checkExitCodeAndThrowExc() { + int status = execChannel.getExitStatus() + if (status != 0) { + throw new SshBadExitCodeException("status = ${status}, details : ${err1S}") + } + } + + void start() { + setStreamsWithParallelLogToSysout() + Runnable r = { onFinish() } + execChannel.setExitListener(r) + + //InputStream inputStream = execChannel.getInputStream() + + execChannel.setCommand(cmd); + execChannel.connect() + log.info "cmd started : ${cmd}" + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshConSet2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshConSet2.groovy index 84bff95a..0a907f8e 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshConSet2.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshConSet2.groovy @@ -12,9 +12,10 @@ class SshConSet2 { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); // public static SshConSet2 defaultSet = new SshConSet2(); - + public boolean showMessage = true public static int defaultPort = 22; + public static int maxRetry = 22; public static String defaultPassword; public static String defaultUser = SystemUtils.USER_NAME; public static File defaultSshKey = new File(SystemUtils.USER_HOME + "/.ssh/id_rsa"); diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshConSet3.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshConSet3.groovy index d7b56bf1..854b1944 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshConSet3.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshConSet3.groovy @@ -1,5 +1,6 @@ package net.sf.jremoterun.utilities.nonjdk.sshsup +import com.jcraft.jsch.ChannelExec import com.jcraft.jsch.ChannelSftp import com.jcraft.jsch.Session import com.sshtools.net.SocketTransport @@ -14,6 +15,9 @@ import com.sshtools.ssh.components.SshKeyPair import com.sshtools.ssh2.Ssh2Client import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.channels.JrrChannelExec +import net.sf.jremoterun.utilities.nonjdk.sshsup.channels.JrrChannelSftp +import net.sf.jremoterun.utilities.nonjdk.sshsup.channels.JschChannelType import java.util.logging.Logger @@ -23,13 +27,21 @@ abstract class SshConSet3 extends SshConSet2 implements Closeable { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public SftpUtils sftpUtils + public JrrChannelExec channelExec; void close() { // sftpUtils.close() if (sftpUtils != null) { sftpUtils.close() } + if(channelExec!=null){ + channelExec.disconnect() + } + + // close method is not public, why ? + } abstract Session getJcraftSession(); @@ -56,11 +68,22 @@ abstract class SshConSet3 extends SshConSet2 implements Closeable { createJcraftConnection() Session session = getJcraftSession(); assert session != null - sftpUtils2.sftp = session.openChannel("sftp") as ChannelSftp + + sftpUtils2.sftp = session.openChannel(JschChannelType.sftp.name()) as JrrChannelSftp sftpUtils2.sftp.connect() + } + JrrChannelExec openExecChannel(){ + if(channelExec==null) { + createJcraftConnection() + Session session = getJcraftSession(); + assert session != null + channelExec = session.openChannel(JschChannelType.exec.name()) as JrrChannelExec + } + return channelExec } + void createNewSftpConn(SftpUtils sftpUtils2) { SocketTransport t = new SocketTransport(host, port); t.setTcpNoDelay(true); diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshHostKeyExtractor.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshHostKeyExtractor.groovy new file mode 100644 index 00000000..6ffbacac --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/SshHostKeyExtractor.groovy @@ -0,0 +1,45 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import com.sshtools.net.SocketTransport +import com.sshtools.ssh.HostKeyVerification +import com.sshtools.ssh.SshClient +import com.sshtools.ssh.SshConnector +import com.sshtools.ssh.SshContext +import com.sshtools.ssh.SshException +import com.sshtools.ssh.components.SshPublicKey +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.util.logging.Level; +import java.util.logging.Logger; + +@CompileStatic +class SshHostKeyExtractor { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static SshPublicKey extractHostKey(String host, int port, String user) { + SshConnector con = SshConnector.createInstance(); + SshPublicKey keyR + + HostKeyVerification hostKeyVerification1 = new HostKeyVerification() { + boolean verifyHost(String name, SshPublicKey key) throws SshException { + keyR = key; + return false; + } + }; + SshContext context = con.getContext(); + context.setHostKeyVerification(hostKeyVerification1); + SocketTransport t = new SocketTransport(host, port); + t.setTcpNoDelay(true); + + try { + SshClient connect = con.connect(t, user, true); + connect.disconnect(); + } catch (SshException e) { + log.log(Level.FINE, "expected exception", e) + } + return keyR; + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/UserInfoJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/UserInfoJrr.groovy new file mode 100644 index 00000000..1cbfe437 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/UserInfoJrr.groovy @@ -0,0 +1,60 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup + +import com.jcraft.jsch.UserInfo +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef + + +import java.util.logging.Logger; + +@CompileStatic +class UserInfoJrr implements UserInfo { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + static { + new ClRef('net.sf.jremoterun.utilities.nonjdk.sshsup.JcraftConnectopnOpener') + } + + public UserInfo original; + public JrrJschSession session; + + UserInfoJrr(UserInfo original, JrrJschSession session) { + this.original = original + this.session = session + } + + @Override + String getPassphrase() { + return original.getPassphrase() + } + + @Override + String getPassword() { + return original.getPassword(); + } + + @Override + boolean promptPassword(String message) { + log.info message + return original.promptPassword(message) + } + + @Override + boolean promptPassphrase(String message) { + log.info message + return original.promptPassphrase(message) + } + + @Override + boolean promptYesNo(String message) { + log.info message + return original.promptYesNo(message) + } + + @Override + void showMessage(String message) { + log.info message + original.showMessage(message) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/AuthState.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/AuthState.groovy new file mode 100644 index 00000000..5f481050 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/AuthState.groovy @@ -0,0 +1,23 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class AuthState { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public final SshAuthCallParentMethod handle; + public AuthStateEnum state = AuthStateEnum.inProgress; + public Throwable exception; + + AuthState(SshAuthCallParentMethod handle) { + this.handle = handle + } + + @Override + String toString() { + return "${handle.getClass().getSimpleName()} ${state} ${exception}" + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/AuthStateEnum.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/AuthStateEnum.groovy new file mode 100644 index 00000000..53481174 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/AuthStateEnum.groovy @@ -0,0 +1,13 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +enum AuthStateEnum { + inProgress, finishedOk, finishedFailed, + ; + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/InitAuth.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/InitAuth.groovy new file mode 100644 index 00000000..ce4c24b5 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/InitAuth.groovy @@ -0,0 +1,41 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import com.jcraft.jsch.JSch +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef; + +import java.util.logging.Logger; + +@CompileStatic +class InitAuth { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + public static volatile boolean inited = false + + static void init() { + if (inited) { + log.info "already inited" + } else { + inited = true + initImpl() + } + } + + static void initImpl() { + SshAuthType.values().toList().each { + putAuth(it,it.className); + } +// putAuth(SshAuthType.none, UserAuthNoneJrr) +// putAuth(SshAuthType.password", UserAuthPasswordJrr) +// putAuth(SshAuthType.keyboard-interactive, UserAuthKeyboardInteractiveJrr) +// putAuth(SshAuthType.publickey, UserAuthPublicKeyJrr) +// putAuth(SshAuthType.gssapi_with_mic, UserAuthGSSAPIWithMICJrr) + } + + static void putAuth(SshAuthType name, ClRef clazz) { + JSch.setConfig('userauth.' + name.customName, clazz.getName()) + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthCallParentMethod.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthCallParentMethod.groovy new file mode 100644 index 00000000..9d064db2 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthCallParentMethod.groovy @@ -0,0 +1,14 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import com.jcraft.jsch.Session +import com.jcraft.jsch.UserAuth +import groovy.transform.CompileStatic + +@CompileStatic +interface SshAuthCallParentMethod { + + boolean startCallSuper(Session session) + + UserAuth getUserAuth(); + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthHandlerJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthHandlerJrr.groovy new file mode 100644 index 00000000..6eb28313 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthHandlerJrr.groovy @@ -0,0 +1,56 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import com.jcraft.jsch.Session +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschSession +import com.jcraft.jsch.JrrSchSessionLog; + +import java.util.logging.Logger; + +@CompileStatic +class SshAuthHandlerJrr { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public static volatile SshAuthHandlerJrr authHandlerJrr = new SshAuthHandlerJrr(); + + boolean handle(SshAuthCallParentMethod handle, Session session) { + AuthState authState = new AuthState(handle); + Class cl = handle.getClass(); + JrrSchSessionLog sessionLog; + long startTime = System.currentTimeMillis() + try { + + if (session instanceof JrrJschSession) { + JrrJschSession jrrSession = (JrrJschSession) session; + jrrSession.auths.add(authState) + sessionLog = jrrSession.jrrSchSessionLog + sessionLog.logMsg "doing ${cl.getSimpleName()}" + }else{ + log.info "auth log not saved due to session not JrrJschSession : ${session.getClass().getName()}" + } + boolean b = handle.startCallSuper(session) + if (b) { + authState.state = AuthStateEnum.finishedOk; + } else { + authState.state = AuthStateEnum.finishedFailed; + } + return b; + } catch (Throwable e) { + authState.exception = e; + authState.state = AuthStateEnum.finishedFailed; + if(sessionLog!=null) { + sessionLog.logMsg "connecting failed ${e}" + } + throw e; + }finally{ + long duration = System.currentTimeMillis() - startTime; + duration = (long)(duration/1000); + log.info "${cl.getSimpleName()} ${session.getHost()} with state ? ${authState.state} within ${duration}s" + if(sessionLog!=null) { + sessionLog.logMsg "${cl.getSimpleName()} finished with state ? ${authState.state} within ${duration}s" + } + } + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthType.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthType.groovy new file mode 100644 index 00000000..c583ede2 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/SshAuthType.groovy @@ -0,0 +1,27 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.classpath.ClRef +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +@CompileStatic +enum SshAuthType implements EnumNameProvider{ + + none( new ClRef('net.sf.jremoterun.utilities.nonjdk.sshsup.auth.UserAuthNoneJrr')), + password(new ClRef('net.sf.jremoterun.utilities.nonjdk.sshsup.auth.UserAuthPasswordJrr')), + keyboard_interactive(new ClRef( 'net.sf.jremoterun.utilities.nonjdk.sshsup.auth.UserAuthKeyboardInteractiveJrr')), + publickey(new ClRef( 'net.sf.jremoterun.utilities.nonjdk.sshsup.auth.UserAuthPublicKeyJrr')), + gssapi_with_mic( new ClRef('net.sf.jremoterun.utilities.nonjdk.sshsup.auth.UserAuthGSSAPIWithMICJrr')), + ; + + String customName; + public ClRef className; + + SshAuthType(Class className) { + + } + SshAuthType(ClRef className) { + customName = name().replace('_','-'); + this.className = className + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthGSSAPIWithMICJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthGSSAPIWithMICJrr.groovy new file mode 100644 index 00000000..cf49cb36 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthGSSAPIWithMICJrr.groovy @@ -0,0 +1,28 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import com.jcraft.jsch.Session +import com.jcraft.jsch.UserAuth +import com.jcraft.jsch.UserAuthGSSAPIWithMICOriginal +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class UserAuthGSSAPIWithMICJrr extends UserAuthGSSAPIWithMICOriginal implements SshAuthCallParentMethod{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + boolean start(Session session) throws Exception { + return SshAuthHandlerJrr.authHandlerJrr.handle(this,session); + } + + @Override + boolean startCallSuper(Session session) { + return super.start(session) + } + + @Override + UserAuth getUserAuth() { + return this + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthKeyboardInteractiveJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthKeyboardInteractiveJrr.groovy new file mode 100644 index 00000000..76e9ed83 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthKeyboardInteractiveJrr.groovy @@ -0,0 +1,30 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import com.jcraft.jsch.Session +import com.jcraft.jsch.UserAuth +import com.jcraft.jsch.UserAuthKeyboardInteractiveOriginal +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +class UserAuthKeyboardInteractiveJrr extends UserAuthKeyboardInteractiveOriginal implements SshAuthCallParentMethod{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + @Override + boolean start(Session session) throws Exception { + return SshAuthHandlerJrr.authHandlerJrr.handle(this,session); + } + + @Override + boolean startCallSuper(Session session) { + return super.start(session) + } + + @Override + UserAuth getUserAuth() { + return this + } + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthNoneJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthNoneJrr.groovy new file mode 100644 index 00000000..7ffaf057 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthNoneJrr.groovy @@ -0,0 +1,39 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import com.jcraft.jsch.Session +import com.jcraft.jsch.UserAuth +import com.jcraft.jsch.UserAuthNoneOriginal +import com.jcraft.jsch.UserAuthNoneWithLogging +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschSession; + +import java.util.logging.Logger; + +@CompileStatic +class UserAuthNoneJrr extends UserAuthNoneWithLogging implements SshAuthCallParentMethod{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + boolean start(Session session) throws Exception { + if (session instanceof JrrJschSession) { + JrrJschSession session2 = (JrrJschSession) session; + schSessionLog = session2.jrrSchSessionLog + } + boolean res = SshAuthHandlerJrr.authHandlerJrr.handle(this,session); + schSessionLog.logMsg("allowed auth methods : ${getMethods()}") + log.info ("allowed auth methods : ${getMethods()}") + return res + } + + @Override + boolean startCallSuper(Session session) { + return super.start(session) + } + + + @Override + UserAuth getUserAuth() { + return this + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthPasswordJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthPasswordJrr.groovy new file mode 100644 index 00000000..76f92e5c --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthPasswordJrr.groovy @@ -0,0 +1,45 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import com.jcraft.jsch.Session +import com.jcraft.jsch.UserAuth +import com.jcraft.jsch.UserAuthPassword +import com.jcraft.jsch.UserAuthPasswordOriginal +import com.jcraft.jsch.UserAuthPasswordWithLogging +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschSession; + +import java.util.logging.Logger; + +@CompileStatic +class UserAuthPasswordJrr extends UserAuthPasswordWithLogging implements SshAuthCallParentMethod{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + @Override + boolean start(Session session) throws Exception { + if (session instanceof JrrJschSession) { + JrrJschSession session2 = (JrrJschSession) session; + schSessionLog = session2.jrrSchSessionLog + if(org.apache.commons.lang.StringUtils.isEmpty(session2.getUserName())){ + log.warn "username not set" + } + if(org.apache.commons.lang.StringUtils.isEmpty(session2.getPassword2())){ + log.warn "password not set" + } + + } + + return SshAuthHandlerJrr.authHandlerJrr.handle(this,session); + } + + @Override + boolean startCallSuper(Session session) { + return super.start(session) + } + + @Override + UserAuth getUserAuth() { + return this + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthPublicKeyJrr.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthPublicKeyJrr.groovy new file mode 100644 index 00000000..9da81899 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/auth/UserAuthPublicKeyJrr.groovy @@ -0,0 +1,50 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.auth + +import com.jcraft.jsch.IdentityRepository +import com.jcraft.jsch.Session +import com.jcraft.jsch.UserAuth +import com.jcraft.jsch.UserAuthPublicKeyOriginal +import com.jcraft.jsch.UserAuthPublicKeyWithLogging +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschSession; + +import java.util.logging.Logger; + +@CompileStatic +class UserAuthPublicKeyJrr extends UserAuthPublicKeyWithLogging implements SshAuthCallParentMethod { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + @Override + boolean start(Session session) throws Exception { + if (session instanceof JrrJschSession) { + JrrJschSession session2 = (JrrJschSession) session; + schSessionLog = session2.jrrSchSessionLog + IdentityRepository repository = session2.getIdentityRepository() + if (repository == null) { + log.warn "IdentityRepository is null" + } else { + Vector identities = repository.getIdentities() + if (identities == null || identities.size() == 0) { + log.warn "Identities is empty or null" + } + } + if (org.apache.commons.lang.StringUtils.isEmpty(session2.getUserName())) { + log.warn "username not set" + } + } + + return SshAuthHandlerJrr.authHandlerJrr.handle(this, session); + } + + @Override + boolean startCallSuper(Session session) { + return super.start(session) + } + + + @Override + UserAuth getUserAuth() { + return this + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelExec.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelExec.groovy new file mode 100644 index 00000000..f9f5f56d --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelExec.groovy @@ -0,0 +1,52 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.channels + +import com.jcraft.jsch.ChannelExecOriginal +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschIO +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschSession +import net.sf.jremoterun.utilities.nonjdk.sshsup.SshCommandExec + +import java.util.logging.Logger; + +@CompileStatic +class JrrChannelExec extends ChannelExecOriginal implements JrrJschSessionMethods{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + JrrJschIO jrrJschIO = JrrJschIO.createJrrJschIOAndSet(this); + + volatile Runnable exitListener; +// JrrJschSession jrrJschSession; + + + JrrChannelExec() { + super() + } + + @Override + void setExitStatus(int status) { + super.setExitStatus(status) + log.info "exit status ${status}" + if(exitListener!=null){ + exitListener.run() + } + } + + SshCommandExec prepareCommand(String cmd){ + SshCommandExec commandExec = new SshCommandExec(this,cmd) + return commandExec; + } + + @Override + void setCommand(byte[] command1) { + String cmd1=new String(command1) + log.info "command = ${command1}" + super.setCommand(command1) + } + + @Override + void setCommand(String command1) { + log.info "command = ${command1}" + super.setCommand(command1) + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelSftp.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelSftp.groovy new file mode 100644 index 00000000..2b4f03ae --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelSftp.groovy @@ -0,0 +1,29 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.channels + +import com.jcraft.jsch.ChannelSftp +import com.jcraft.jsch.ChannelSftpOriginal +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschIO +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschSession; + +import java.util.logging.Logger; + +@CompileStatic +class JrrChannelSftp extends ChannelSftpOriginal implements JrrJschSessionMethods{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + JrrJschIO jrrJschIO = JrrJschIO.createJrrJschIOAndSet(this) + + volatile Runnable exitListener; +// JrrJschSession jrrJschSession; + + @Override + void setExitStatus(int status) { + super.setExitStatus(status) + log.info "exit status ${status}" + if(exitListener!=null){ + exitListener.run() + } + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelShell.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelShell.groovy new file mode 100644 index 00000000..37681eb7 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrChannelShell.groovy @@ -0,0 +1,38 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.channels + +import com.jcraft.jsch.ChannelShellOriginal +import com.jcraft.jsch.JSchException +import com.jcraft.jsch.JrrJschSessionOriginal +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschIO +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschSession; + +import java.util.logging.Logger; + +@CompileStatic +class JrrChannelShell extends ChannelShellOriginal implements JrrJschSessionMethods { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + JrrJschIO jrrJschIO = JrrJschIO.createJrrJschIOAndSet(this) + volatile Runnable exitListener; +// JrrJschSession jrrJschSession; + + JrrChannelShell() { + super() + } + + + @Override + void setExitStatus(int status) { + super.setExitStatus(status) + log.info "exit status ${status}" + if (exitListener != null) { + exitListener.run() + } + } + + + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrJschSessionMethods.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrJschSessionMethods.groovy new file mode 100644 index 00000000..7cbe6c94 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JrrJschSessionMethods.groovy @@ -0,0 +1,23 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.channels + +import com.jcraft.jsch.Session +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschIO +import net.sf.jremoterun.utilities.nonjdk.sshsup.JrrJschSession + +@CompileStatic +interface JrrJschSessionMethods { + +// void setJrrJschSession(JrrJschSession jrrJschSession) + +// void setSession(Session session) + +// void onChannelClosedNotify(); + + JrrJschIO getJrrJschIO(); + + void setExitListener(Runnable r); + + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JschChannelType.groovy b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JschChannelType.groovy new file mode 100644 index 00000000..a8f12674 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/sshsup/channels/JschChannelType.groovy @@ -0,0 +1,68 @@ +package net.sf.jremoterun.utilities.nonjdk.sshsup.channels + +import com.jcraft.jsch.* +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.nonjdk.enumutils.EnumNameProvider + +/** + {@link com.jcraft.jsch.Channel#getChannel(java.lang.String)} + */ +@CompileStatic +enum JschChannelType implements EnumNameProvider { + + session(ChannelSessionOriginal), + shell(JrrChannelShell), + exec(JrrChannelExec), + x11(ChannelX11Original), + sftp(JrrChannelSftp), + subsystem(ChannelSubsystem), + forwarded_tcpip(ChannelForwardedTCPIPOriginal), + ; + +// if(type.equals("session")){ +// return new ChannelSession(); +// } +// if(type.equals("shell")){ +// return new ChannelShell(); +// } +// if(type.equals("exec")){ +// return new ChannelExec(); +// } +// if(type.equals("x11")){ +// return new ChannelX11(); +// } +// if(type.equals("auth-agent@openssh.com")){ +// return new ChannelAgentForwarding(); +// } +// if(type.equals("direct-tcpip")){ +// return new ChannelDirectTCPIP(); +// } +// if(type.equals("forwarded-tcpip")){ +// return new ChannelForwardedTCPIP(); +// } +// if(type.equals("sftp")){ +// return new ChannelSftp(); +// } +// if(type.equals("subsystem")){ +// return new ChannelSubsystem(); +// } + + + public Class clazz; + + String customName; + + JschChannelType(Class clazz) { + this.clazz = clazz + customName = name().replace('_', '-') + } + + public static List all = (List) values().toList() + public static Map allMap = all.collectEntries { [(it.customName): it] } + +// static JschChannelType resolveFromString(String s){ +// return all.find {it.name() == s} +// } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/staticanalizer/AnalizeJavaSourceFile.groovy b/src/net/sf/jremoterun/utilities/nonjdk/staticanalizer/AnalizeJavaSourceFile.groovy index b9a4caef..dcbf1363 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/staticanalizer/AnalizeJavaSourceFile.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/staticanalizer/AnalizeJavaSourceFile.groovy @@ -86,7 +86,8 @@ class AnalizeJavaSourceFile extends AnalizeCommon { List analizeFile(File f) { assert f.name.endsWith('.java') - CompilationUnit cu = JavaParser.parse(f); +// CompilationUnit cu = JavaParser.parse(f); + CompilationUnit cu = new JavaParser().parse(f).result.get(); // Name package23 = cu.packageDeclaration.get().name // ClassOrInterfaceDeclaration typeDeclaration = cu.getPrimaryType().get() as ClassOrInterfaceDeclaration diff --git a/src/net/sf/jremoterun/utilities/nonjdk/staticanalizer/ExpressionFinder.groovy b/src/net/sf/jremoterun/utilities/nonjdk/staticanalizer/ExpressionFinder.groovy index 76262db6..c2517509 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/staticanalizer/ExpressionFinder.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/staticanalizer/ExpressionFinder.groovy @@ -67,7 +67,7 @@ class ExpressionFinder extends ClassCodeVisitorSupport { void castExpressionImpl2(Expression parentExpression, ConstantExpression ce, boolean isFileExp){ String text = ce.text ElementMethodGroovy elementMethodGroovy = new ElementMethodGroovy(); - elementMethodGroovy.expression=parentExpression; + elementMethodGroovy.expression =parentExpression; elementMethodGroovy.fieldName = methodName elementMethodGroovy.className = elName elementMethodGroovy.printablePath = printablePath diff --git a/src/net/sf/jremoterun/utilities/nonjdk/str2obj/DateOnlyBackConverter.groovy b/src/net/sf/jremoterun/utilities/nonjdk/str2obj/DateOnlyBackConverter.groovy new file mode 100644 index 00000000..9af0236d --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/str2obj/DateOnlyBackConverter.groovy @@ -0,0 +1,58 @@ +package net.sf.jremoterun.utilities.nonjdk.str2obj + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.str2obj.types.DateOnlyBack +import org.joda.time.LocalDate + +import java.lang.reflect.Type +import java.text.SimpleDateFormat +import java.util.logging.Logger + +@CompileStatic +class DateOnlyBackConverter implements StringToObjectConverterI2 { + + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + @Override + DateOnlyBack convert(String str, Type genericArg) { + int day; + if (str.length() == 8) { + // assume date fully specified in format YYYYMMDD + int year = str.substring(0, 4) as int; + int month = str.substring(4, 6) as int; + day = str.substring(6) as int; + if (day > 31) { + throw new Exception("day need be less 32 : ${day}") + } + if (month > 12) { + throw new Exception("month need be less 13 : ${day}") + } + + return new DateOnlyBack(new LocalDate(year, month, day)); + } + day = Integer.parseInt(str); + return new DateOnlyBack(getBackDay(day, new LocalDate())); + } + + static LocalDate getBackDay(int day, LocalDate now) { + if (day < 1) { + throw new Exception("day need be positive : ${day}") + } + if (day > 31) { + throw new Exception("day need be less 31 : ${day}") + } + int month = now.getMonthOfYear(); + int year = now.getYear(); + if (day > now.getDayOfMonth()) { + if (month == 1) { + year = year - 1; + month = 12; + } else { + month = month - 1; + } + } + return new LocalDate(year, month, day); + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/str2obj/ListConverter.groovy b/src/net/sf/jremoterun/utilities/nonjdk/str2obj/ListConverter.groovy index 83bbbf0e..30f4650c 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/str2obj/ListConverter.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/str2obj/ListConverter.groovy @@ -38,7 +38,9 @@ class ListConverter implements StringToObjectConverterI { throw new IllegalArgumentException("not ParameterizedType : ${genericArg}") // return null } - Type[] typeArguments = genericArg.getActualTypeArguments() + ParameterizedType pt = (ParameterizedType)genericArg; +// Type[] typeArguments = JrrClassUtils.invokeJavaMethod(genericArg,'getActualTypeArguments') as Type[] + Type[] typeArguments = pt.getActualTypeArguments() if (typeArguments.length != 1) { throw new IllegalArgumentException("type should be 1 : ${typeArguments}") } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/str2obj/RegisterConverters.groovy b/src/net/sf/jremoterun/utilities/nonjdk/str2obj/RegisterConverters.groovy index 1d1f7a3d..8df99f0c 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/str2obj/RegisterConverters.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/str2obj/RegisterConverters.groovy @@ -33,6 +33,7 @@ class RegisterConverters implements Runnable { regConverters3(cust, new SocketConverter()) regConverters3(cust, new ClassConverter()) regConverters3(cust, new InetAddressConverter()) + regConverters3(cust, new DateOnlyBackConverter()) // log.info "converter registered" } @@ -46,7 +47,7 @@ class RegisterConverters implements Runnable { static Class deriveType(Class clazz) { - Type[] interfaces = clazz.genericInterfaces + Type[] interfaces = clazz.getGenericInterfaces(); List paramType = (List)interfaces.toList().findAll { it instanceof ParameterizedType } ParameterizedType parameterizedType = paramType.find { it.rawType == StringToObjectConverterI2 } Class aClass = parameterizedType.actualTypeArguments[0] diff --git a/src/net/sf/jremoterun/utilities/nonjdk/str2obj/types/DateOnlyBack.groovy b/src/net/sf/jremoterun/utilities/nonjdk/str2obj/types/DateOnlyBack.groovy new file mode 100644 index 00000000..5d9aaae6 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/str2obj/types/DateOnlyBack.groovy @@ -0,0 +1,48 @@ +package net.sf.jremoterun.utilities.nonjdk.str2obj.types + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils +import org.joda.time.LocalDate; + +import java.util.logging.Logger; + +@CompileStatic +class DateOnlyBack implements Serializable { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public LocalDate date; + + DateOnlyBack(LocalDate date) { + this.date = date + assert date!=null + } + + + /** + * @return If month < 10 , contains leading 0 + */ + String getMonthOfYear() { + return convertNumber(date.getMonthOfYear()) + } + + /** + * @return If day < 10 , contains leading 0 + */ + String getDayOfYear() { + return convertNumber(date.getDayOfMonth()) + } + + static String convertNumber(int number1) { + String result = number1 + '' + if (number1 < 10) { + result = '0' + result; + } + return result + + } + + @Override + String toString() { + return date.toString() + } +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/svn/SvnUtils.groovy b/src/net/sf/jremoterun/utilities/nonjdk/svn/SvnUtils.groovy index 01caccf3..be190316 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/svn/SvnUtils.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/svn/SvnUtils.groovy @@ -1,9 +1,12 @@ package net.sf.jremoterun.utilities.nonjdk.svn; import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.nonjdk.FileUtilsJrr +import net.sf.jremoterun.utilities.nonjdk.git.SvnRef import net.sf.jremoterun.utilities.nonjdk.git.SvnSpec import net.sf.jremoterun.utilities.nonjdk.git.UrlSymbolsReplacer import org.apache.commons.io.FileUtils +import org.apache.commons.lang.StringUtils import java.util.logging.Logger; import groovy.transform.CompileStatic; @@ -14,13 +17,14 @@ class SvnUtils { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public static String svnDirPrefix = 'svn' SvnUtils2 svnUtils2 = new SvnUtils2() File svnRepo File gitTmpDir SvnUtils(File gitRepo, File gitTmpDir) { - svnRepo = gitRepo.child('svn') + svnRepo = gitRepo.child(svnDirPrefix) svnRepo.mkdir() assert svnRepo.exists() @@ -29,23 +33,43 @@ class SvnUtils { } void checkoutSvnRefImpl(SvnSpec svnRef, File workingCopyDirectory) { - svnUtils2.checkoutSvnRefImpl(svnRef.repo,workingCopyDirectory) + String fullPath = svnRef.repo; + if (svnRef instanceof SvnRef) { + String pathInRepo = svnRef.branch + if (StringUtils.isNotEmpty(pathInRepo)) { + if (!pathInRepo.startsWith('/')) { + fullPath += '/'; + } + fullPath += pathInRepo; + } + } + if (svnRef.runExport) { + svnUtils2.exportSvnRefImpl(fullPath, workingCopyDirectory) + } else { + svnUtils2.checkoutSvnRefImpl(fullPath, workingCopyDirectory) + } + } - File svnCheckout(SvnSpec svnRef) { + File getFileIfDownloaded(SvnSpec svnRef) { String checkoutDirSuffix = UrlSymbolsReplacer.replaceBadSymbols(svnRef.repo) - File toDir3 = svnRepo.child(checkoutDirSuffix) + File toDir3 = svnRepo.child(svnRef.repoPrefix + checkoutDirSuffix) + return toDir3 + } + + File svnCheckout(SvnSpec svnRef) { + File toDir3 = getFileIfDownloaded(svnRef) if (toDir3.exists()) { return toDir3 } - File tmpGitDir = findGitDownloadDir("svn") + File tmpGitDir = findGitDownloadDir(svnDirPrefix + svnRef.repoPrefix) checkoutSvnRefImpl(svnRef, tmpGitDir) if (toDir3.exists()) { assert toDir3.deleteDir() } if (!tmpGitDir.renameTo(toDir3)) { log.info("can't rename ${tmpGitDir} to ${toDir3}, tring copy and delete") - FileUtils.copyDirectory(tmpGitDir, toDir3) + FileUtilsJrr.copyDirectory(tmpGitDir, toDir3) if (!FileUtils.deleteQuietly(tmpGitDir)) { log.info("failed delete ${tmpGitDir}") } @@ -67,6 +91,4 @@ class SvnUtils { } - - } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/svn/SvnUtils2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/svn/SvnUtils2.groovy index c8897564..e352db55 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/svn/SvnUtils2.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/svn/SvnUtils2.groovy @@ -2,14 +2,18 @@ package net.sf.jremoterun.utilities.nonjdk.svn import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils +import net.sf.jremoterun.utilities.classpath.ClRef import net.sf.jremoterun.utilities.nonjdk.git.SvnSpec import net.sf.jremoterun.utilities.nonjdk.git.UrlSymbolsReplacer import org.apache.commons.io.FileUtils +import org.tmatesoft.svn.core.SVNProperties import org.tmatesoft.svn.core.SVNURL import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager import org.tmatesoft.svn.core.io.SVNRepository import org.tmatesoft.svn.core.io.SVNRepositoryFactory +import org.tmatesoft.svn.core.wc2.SvnCat import org.tmatesoft.svn.core.wc2.SvnCheckout +import org.tmatesoft.svn.core.wc2.SvnExport import org.tmatesoft.svn.core.wc2.SvnOperationFactory import org.tmatesoft.svn.core.wc2.SvnTarget @@ -20,35 +24,104 @@ class SvnUtils2 { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + int initBufferSize = 1_000_000; - void checkoutSvnRefImpl(String svnRef, File workingCopyDirectory) { - SVNURL svnurl = SVNURL.parseURIDecoded(svnRef) - SVNRepository svnRepo = SVNRepositoryFactory.create(svnurl); - svnRepo.authenticationManager = getAuth() - configureRepo(svnRepo) - long remoteRevision = svnRepo.latestRevision - log.info "${remoteRevision}" - final SvnOperationFactory svnOperationFactory = new SvnOperationFactory(); - svnOperationFactory.authenticationManager = getAuth() + long checkoutSvnRefImpl(String svnRef, File workingCopyDirectory) { +// SVNRepository svnRepo = SVNRepositoryFactory.create(svnurl); +// svnRepo.authenticationManager = getAuth() +// configureRepo(svnRepo) +// long remoteRevision = svnRepo.latestRevision +// log.info "${remoteRevision}" + final SvnOperationFactory svnOperationFactory = createSvnOperationFactory() try { final SvnCheckout checkout = svnOperationFactory.createCheckout(); - checkout.setSource(SvnTarget.fromURL(svnurl)); + checkout.setSource(createSvnTarget(svnRef)); + checkout.setSingleTarget(SvnTarget.fromFile(workingCopyDirectory)); + prepare(checkout) + Long revision = checkout.run(); +// log.info "${long revision}" +// log.info "${checkout}" +// log.info "checkout done" + return revision + } finally { + disposeOperation(svnOperationFactory); + } + } + + long exportSvnRefImpl(String svnRef, File workingCopyDirectory) { +// SVNRepository svnRepo = SVNRepositoryFactory.create(svnurl); +// svnRepo.authenticationManager = getAuth() +// configureRepo(svnRepo) +// long remoteRevision = svnRepo.latestRevision +// log.info "${remoteRevision}" + final SvnOperationFactory svnOperationFactory = createSvnOperationFactory() + try { + final SvnExport checkout = svnOperationFactory.createExport(); + checkout.setSource(createSvnTarget(svnRef)); checkout.setSingleTarget(SvnTarget.fromFile(workingCopyDirectory)); - long run3 = checkout.run(); - log.info "${run3}" - log.info "${checkout}" - log.info "checkout done" + prepare(checkout) + Long revision = checkout.run(); +// log.info "${revision}" +// log.info "${checkout}" +// log.info "checkout done" + return revision + } finally { + disposeOperation(svnOperationFactory); + } + } + + + + byte[] receiveContentSvnRefImpl(String svnRef) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(initBufferSize); + receiveContentSvnRefImpl(svnRef, byteArrayOutputStream) + return byteArrayOutputStream.toByteArray() + } + + + SVNProperties receiveContentSvnRefImpl(String svnRef, OutputStream out) { + // see impl in + new ClRef('org.tmatesoft.svn.core.internal.wc2.remote.SvnRemoteCat') + final SvnOperationFactory svnOperationFactory = createSvnOperationFactory() + try { + final SvnCat checkout = svnOperationFactory.createCat(); + checkout.setSingleTarget(createSvnTarget(svnRef)); + checkout.setOutput(out) + prepare(checkout) + SVNProperties sVNProperties = checkout.run(); + return sVNProperties } finally { - svnOperationFactory.dispose(); + disposeOperation(svnOperationFactory); } } - ISVNAuthenticationManager getAuth(){ + + SvnOperationFactory createSvnOperationFactory() { + final SvnOperationFactory svnOperationFactory = new SvnOperationFactory(); + svnOperationFactory.authenticationManager = getAuth() + return svnOperationFactory; + } + + void disposeOperation(SvnOperationFactory svnOperationFactory){ + svnOperationFactory.dispose() + } + + void prepare(org.tmatesoft.svn.core.wc2.SvnOperation svnOperation){ + } + + SvnTarget createSvnTarget(String svnRef) { + SVNURL svnurl = SVNURL.parseURIEncoded(svnRef); + SvnTarget target = SvnTarget.fromURL(svnurl) + return target; + } + + + ISVNAuthenticationManager getAuth() { return null } - void configureRepo(SVNRepository svnRepo){ + void configureRepo(SVNRepository svnRepo) { // set here: // svn user, password // proxy : BasicAuthenticationManager.setProxy diff --git a/src/net/sf/jremoterun/utilities/nonjdk/swing/MyTextArea.groovy b/src/net/sf/jremoterun/utilities/nonjdk/swing/MyTextArea.groovy index ca6f0360..0c5261c8 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/swing/MyTextArea.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/swing/MyTextArea.groovy @@ -1,20 +1,19 @@ -package net.sf.jremoterun.utilities.nonjdk.swing; +package net.sf.jremoterun.utilities.nonjdk.swing -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; -import org.fife.ui.rtextarea.RTextArea; -import org.fife.ui.rtextarea.RTextScrollPane; -import javax.swing.*; -import java.awt.*; -import java.awt.datatransfer.StringSelection; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea +import org.fife.ui.rtextarea.RTextArea +import org.fife.ui.rtextarea.RTextScrollPane + +import javax.swing.* +import java.awt.* +import java.awt.datatransfer.StringSelection +import java.awt.event.ActionEvent +import java.awt.event.ActionListener public class MyTextArea extends RSyntaxTextArea { -private static final Logger log = LogManager.getLogger(); + private long editsTry = 0; diff --git a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/AdminPage2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/AdminPage2.groovy index 57710b97..ab642460 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/AdminPage2.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/AdminPage2.groovy @@ -30,12 +30,6 @@ public class AdminPage2 extends RstaRunner { } - @Override - public void runCode() { -// getParams().put("tabWindow", (TabWindow) defaultView -// .getWindowParent()); - super.runCode(); - } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/Connection.java b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/Connection.java index 7bc7d3c6..e9908e50 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/Connection.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/Connection.java @@ -1,8 +1,8 @@ package net.sf.jremoterun.utilities.nonjdk.tcpmon; import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; import net.sf.jremoterun.utilities.nonjdk.swing.MyTextArea; -import org.apache.logging.log4j.LogManager; import org.fife.ui.rtextarea.RTextScrollPane; import javax.swing.*; @@ -17,6 +17,8 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.logging.Level; +import java.util.logging.Logger; /** * a connection listens to a single current connection @@ -24,7 +26,8 @@ @CompileStatic class Connection extends Thread { - private static final org.apache.logging.log4j.Logger log = LogManager.getLogger(); + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public Listener listener; @@ -500,7 +503,7 @@ public void halt() { } outSocket = null; } catch (final Exception e) { - log.info("", e); + log.log(Level.INFO,"", e); } } @@ -513,7 +516,7 @@ public void remove() { listener.tableModel.removeRow(index + 1); listener.connections.remove(index); } catch (final Exception e) { - log.info("index:=" + index + this, e); + log.log(Level.INFO,"index:=" + index + this, e); } } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/Listener.java b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/Listener.java index f5823565..1adabc79 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/Listener.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/Listener.java @@ -2,10 +2,10 @@ import groovy.transform.CompileStatic; import net.infonode.docking.*; +import net.sf.jremoterun.utilities.FileOutputStream2; +import net.sf.jremoterun.utilities.JrrClassUtils; import net.sf.jremoterun.utilities.nonjdk.idwutils.IdwUtils; import net.sf.jremoterun.utilities.nonjdk.idwutils.MyDockingWindowTitleProvider; -import net.sf.jremoterun.utilities.FileOutputStream2; -import org.apache.logging.log4j.LogManager; import javax.swing.*; import javax.swing.event.ChangeEvent; @@ -25,6 +25,8 @@ import java.nio.charset.Charset; import java.util.Iterator; import java.util.Vector; +import java.util.logging.Level; +import java.util.logging.Logger; /** * this is one of the tabbed panels that acts as the actual proxy @@ -32,7 +34,8 @@ @CompileStatic public class Listener { - private static final org.apache.logging.log4j.Logger log = LogManager.getLogger(); + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + public final JComboBox reqStyle = new JComboBox(new Vector( Tcpmon.syntaxisFields.keySet())); @@ -520,7 +523,7 @@ public void stop() { tPortField.setEditable(true); isProxyBox.setEnabled(true); } catch (final Exception e) { - log.info("", e); + log.log(Level.INFO,"", e); } } @@ -607,7 +610,7 @@ public void save() { out.close(); } catch (final Exception e) { - log.info("", e); + log.log(Level.INFO,"", e); } } } @@ -635,7 +638,7 @@ public void resend() { // Fix Content-Length HTTP headers if (text.startsWith("POST ") || text.startsWith("GET ")) { - log.warn("IN CL"); + log.warning("IN CL"); int pos1, pos2, pos3; final String body; String headers; @@ -681,7 +684,7 @@ public void resend() { connection.setOutputTextStyle(conn.outputText .getSyntaxEditingStyle()); } catch (final Exception e) { - log.info("", e); + log.log(Level.INFO,"", e); } } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/RestrictedTextField.java b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/RestrictedTextField.java index b87b4ac3..de251dcd 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/RestrictedTextField.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/RestrictedTextField.java @@ -1,7 +1,6 @@ package net.sf.jremoterun.utilities.nonjdk.tcpmon; import groovy.transform.CompileStatic; -import org.apache.logging.log4j.LogManager; import javax.swing.*; import javax.swing.text.AttributeSet; @@ -15,7 +14,7 @@ @CompileStatic class RestrictedTextField extends JTextField { - private static final org.apache.logging.log4j.Logger log = LogManager.getLogger(); + protected String validText; diff --git a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SlowLinkSimulator.java b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SlowLinkSimulator.java index d8163b24..8db55143 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SlowLinkSimulator.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SlowLinkSimulator.java @@ -1,15 +1,19 @@ package net.sf.jremoterun.utilities.nonjdk.tcpmon; import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.logging.log4j.LogManager; +import java.util.logging.Level; +import java.util.logging.Logger; + /** * class to simulate slow connections by slowing down the system */ @CompileStatic public class SlowLinkSimulator { - private static final org.apache.logging.log4j.Logger log = LogManager.getLogger(); + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); public final int delayBytes; @@ -77,7 +81,7 @@ public void pump(final int bytes) { try { Thread.sleep(delay); } catch (final InterruptedException e) { - log.info(e); + log.log(Level.INFO,"",e); } } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SocketRR.java b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SocketRR.java index 7ea35ab6..21b2ed4e 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SocketRR.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SocketRR.java @@ -1,6 +1,7 @@ package net.sf.jremoterun.utilities.nonjdk.tcpmon; import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; import net.sf.jremoterun.utilities.nonjdk.swing.MyTextArea; import org.apache.logging.log4j.LogManager; @@ -9,6 +10,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; +import java.util.logging.Level; +import java.util.logging.Logger; /** * this class handles the pumping of data from the incoming socket to the @@ -17,7 +20,7 @@ @CompileStatic public class SocketRR extends Thread { - private static final org.apache.logging.log4j.Logger log = LogManager.getLogger(); + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); public Socket inSocket = null; @@ -121,7 +124,7 @@ public void run() { try { len1 = in.read(buffer, saved, len); } catch (final Exception ex) { - log.info(ex); + log.log(Level.INFO,"",ex); if (done && saved == 0) { break a; } @@ -149,7 +152,7 @@ public void run() { if (kk != -1) { final int kk2 = newData.indexOf('\n', kk); if (kk2 == -1) { - log.warn("stange data not host end: " + newData); + log.warning("stange data not host end: " + newData); } else { final StringBuffer newData1 = new StringBuffer(); // if (kk > 0) { @@ -215,7 +218,7 @@ public void run() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - log.warn("clearing text for"); + log.warning("clearing text for"); textArea.setText(" ... clearing text for ...\n" + newData2); } @@ -235,7 +238,7 @@ public void run() { // we'll let the other side control when we're done // if ( inSocket != null ) done = true ; } catch (final Exception e) { - log.info("", e); + log.log(Level.INFO,"", e); } finally { done = true; try { @@ -249,7 +252,7 @@ public void run() { out = null; } } catch (final Exception e) { - log.info("", e); + log.log(Level.INFO,"", e); } try { if (in != null) { @@ -261,8 +264,7 @@ public void run() { in = null; } } catch (final Exception e) { - log.info("", e); - ; + log.log(Level.INFO,"", e); } myConnection.wakeUp(); } @@ -288,7 +290,7 @@ public void halt() { out = null; done = true; } catch (final Exception e) { - log.info("", e); + log.log(Level.INFO,"", e); } } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SocketWaiter.java b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SocketWaiter.java index 4da0a2c5..47889ca4 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SocketWaiter.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/tcpmon/SocketWaiter.java @@ -1,12 +1,15 @@ package net.sf.jremoterun.utilities.nonjdk.tcpmon; import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; import org.apache.logging.log4j.LogManager; import javax.swing.*; import java.awt.*; import java.net.ServerSocket; import java.net.Socket; +import java.util.logging.Level; +import java.util.logging.Logger; /** * wait for incoming connections, spawn a connection thread when stuff comes @@ -15,7 +18,7 @@ @CompileStatic public class SocketWaiter extends Thread { - private static final org.apache.logging.log4j.Logger log = LogManager.getLogger(); + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); public ServerSocket sSocket = null; @@ -94,7 +97,7 @@ public void halt() { sSocket.close(); } } catch (final Exception e) { - log.info("", e); + log.log(Level.INFO,"", e); } } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/timer/AdjustPeriodTimer.java b/src/net/sf/jremoterun/utilities/nonjdk/timer/AdjustPeriodTimer.java index 1cd6a429..666b3cb4 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/timer/AdjustPeriodTimer.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/timer/AdjustPeriodTimer.java @@ -40,10 +40,20 @@ public AdjustPeriodTimer() { super.setTask(new TimerTask()); } + /** + * + * @param updateTime in ms + * @param task + */ public AdjustPeriodTimer(final long updateTime, final Runnable task) { this(updateTime, TimerStyle.Consecutive, task); } + /** + * @param updateTime milli seconds + * @param timerStyle + * @param task + */ public AdjustPeriodTimer(final long updateTime, final TimerStyle timerStyle, final Runnable task) { // super(timerStyle, new TimerTask(), updateTime); setPeriod(updateTime); diff --git a/src/net/sf/jremoterun/utilities/nonjdk/timer/CronTimer.java b/src/net/sf/jremoterun/utilities/nonjdk/timer/CronTimer.java index e936f30b..5db137e0 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/timer/CronTimer.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/timer/CronTimer.java @@ -30,6 +30,12 @@ public class CronTimer extends TimerController implements CronTimerMBean { private List cronExpressions; + + public CronTimer(final Runnable task) { + this.task = task; + // this.cronExpressions = cronExpression; + } + public void start() { if (timer.isTimerRunning()) { // log.warn("timer is running"); @@ -82,10 +88,6 @@ public void setCronExpressions(final List cronExpressions) { timer.reEvauateNextRun(); } - public CronTimer(final Runnable task) { - this.task = task; - // this.cronExpressions = cronExpression; - } @Override protected Date isRunNow() { diff --git a/src/net/sf/jremoterun/utilities/nonjdk/timer/JrrTimerTask2.java b/src/net/sf/jremoterun/utilities/nonjdk/timer/JrrTimerTask2.java index 21ef73fb..79ce49e0 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/timer/JrrTimerTask2.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/timer/JrrTimerTask2.java @@ -13,7 +13,7 @@ public class JrrTimerTask2 { - private static final Logger log = LogManager.getLogger(); + public Object lock = new Object(); diff --git a/src/net/sf/jremoterun/utilities/nonjdk/timer/Timer.java b/src/net/sf/jremoterun/utilities/nonjdk/timer/Timer.java index 8dfb71ea..8a78e9c4 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/timer/Timer.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/timer/Timer.java @@ -26,6 +26,9 @@ public class Timer { private volatile long lastRunBefore = -1; + public static long notImportantTimeDiffInMS = 30000; + public static long timeDiffForHebirnateRecheck = 1000 * 60 * 5; + // public static volatile boolean catchDebug = false; public static Runnable debugWaitNextRun; @@ -57,7 +60,8 @@ public class Timer { // private boolean timerRunning = false; - private final Object wakeUpLock = new Object(); +// private final Object wakeUpLock = new Object(); + private final WaitNotifyMethods2 wakeUpLock = new WaitNotifyMethods2(); // protected final Object lock = new Object(); @@ -93,6 +97,20 @@ public void stop() { } } + + private Date nextFireDateDebug; + + + /** + * Only in debug purpose, as nextFireTime can be changed :
    + *
  • user may ask run earlier + *
  • computer can go to hibernate + *
+ */ + public Date getNextFireTimeDebug() { + return nextFireDateDebug; + } + public Date getStartDate() { return startDate; } @@ -103,6 +121,8 @@ public void taskWasRunNow() { reEvauateNextRun(); } + public volatile Date debugLastTimeStartedWait; + protected void waitNextRun() throws InterruptedException { Date nextFireDate2 = controller.isRunNow(); if (nextFireDate2 != null) { @@ -121,12 +141,13 @@ protected void waitNextRun() throws InterruptedException { return; } } + nextFireDateDebug = nextFireDate2; reevalute = false; try { // boolean doNewThisMethod = false; final long currcentTime; final long waitTime; - synchronized (wakeUpLock) { + synchronized (wakeUpLock.lock) { currcentTime = System.currentTimeMillis(); waitTime = nextFireDate3 - currcentTime; inSleep = true; @@ -138,7 +159,8 @@ protected void waitNextRun() throws InterruptedException { if (debugWaitNextRun != null) { debugWaitNextRun.run(); } - WaitNotifyMethods.wait(wakeUpLock, waitTime); + debugLastTimeStartedWait = new Date(); + wakeUpLock.wait2(waitTime); // if (catchDebug) { // log.info(getController().toString()); // } @@ -153,13 +175,17 @@ protected void waitNextRun() throws InterruptedException { } inSleep = false; } - if (waitTime > 1000 * 60 * 5) { + if (waitTime > timeDiffForHebirnateRecheck) { long nowAfterWait = System.currentTimeMillis(); - if (Math.abs(nowAfterWait - nextFireDate3) > 1000) { + if (Math.abs(nowAfterWait - nextFireDate3) > notImportantTimeDiffInMS) { // may be caused by hibernate event - notifyMissingTimeEvent(nextFireDate2); - waitNextRun(); - return; + boolean needRun2 = notifyMissingTimeEvent(nextFireDate2); + if(needRun2){ + + }else { + waitNextRun(); + return; + } } } if (reevalute) { @@ -200,10 +226,10 @@ public boolean reEvauateNextRun() { if (waitingThread == null) { return false; } - synchronized (wakeUpLock) { + synchronized (wakeUpLock.lock) { if ((waitingThread != null) && inSleep) { reevalute = true; - WaitNotifyMethods.notify(wakeUpLock); + wakeUpLock.notify2(); return true; } } @@ -274,8 +300,11 @@ public Date getLastRun() { return new Date(lastRun); } - public void notifyMissingTimeEvent(Date date) { + public static boolean runTaskIfMissesTime = true; + + protected boolean notifyMissingTimeEvent(Date date) { log.info("missing fire date: " + date); + return runTaskIfMissesTime; } public void setLastRun(Date lastRun) { diff --git a/src/net/sf/jremoterun/utilities/nonjdk/timer/TimerPeriod.java b/src/net/sf/jremoterun/utilities/nonjdk/timer/TimerPeriod.java index 9e938fc6..b84c53b9 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/timer/TimerPeriod.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/timer/TimerPeriod.java @@ -14,12 +14,15 @@ public class TimerPeriod extends TimerController { private transient static final Logger log = LogManager.getLogger(); - private net.sf.jremoterun.utilities.nonjdk.timer.TimerStyle timerStyle; + private TimerStyle timerStyle; private Runnable task; - protected net.sf.jremoterun.utilities.nonjdk.timer.Timer timer = new net.sf.jremoterun.utilities.nonjdk.timer.Timer(this); + protected Timer timer = new Timer(this); + /** + * period in milli seconds + */ private long period; private boolean runNow = true; @@ -28,6 +31,9 @@ public TimerPeriod() { } + /** + * ignore, if already running + */ public void start() { if (timer.isTimerRunning()) { log.warn("timer is running"); @@ -36,6 +42,9 @@ public void start() { } } + /** + * Throw exception if already started + */ public void start2() { if (timer.isTimerRunning()) { // log.warn("timer is running"); @@ -51,7 +60,7 @@ public void start2() { * @param task */ public TimerPeriod(final long period, final Runnable task) { - this(net.sf.jremoterun.utilities.nonjdk.timer.TimerStyle.Consecutive, task, period); + this(TimerStyle.Consecutive, task, period); } /** @@ -60,7 +69,7 @@ public TimerPeriod(final long period, final Runnable task) { * @param period * in ms */ - public TimerPeriod(final net.sf.jremoterun.utilities.nonjdk.timer.TimerStyle timerStyle, final Runnable task, final long period) { + public TimerPeriod(final TimerStyle timerStyle, final Runnable task, final long period) { this.timerStyle = timerStyle; this.task = task; this.period = period; @@ -95,7 +104,7 @@ protected void runTask() { break; case NoWait: final Thread thread = new Thread(task); - net.sf.jremoterun.utilities.nonjdk.timer.Timer.setThreadName(thread, "Jrr Timer Run"); + Timer.setThreadName(thread, "Jrr Timer Run"); thread.start(); break; default: @@ -108,6 +117,9 @@ public long getPeriod() { return period; } + /** + * Period in ms + */ public synchronized void setPeriod(final long period) { if (period <= 0) { throw new TimerException("period <= 0"); @@ -129,7 +141,7 @@ public boolean runTaskNowIfNotSleep() { } - public net.sf.jremoterun.utilities.nonjdk.timer.TimerStyle getTimerStyle() { + public TimerStyle getTimerStyle() { return timerStyle; } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/timer/TooShortPeriodListener.java b/src/net/sf/jremoterun/utilities/nonjdk/timer/TooShortPeriodListener.java index ba881698..fb046e5e 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/timer/TooShortPeriodListener.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/timer/TooShortPeriodListener.java @@ -1,5 +1,8 @@ package net.sf.jremoterun.utilities.nonjdk.timer; +import groovy.transform.CompileStatic; + +@CompileStatic public interface TooShortPeriodListener { /** diff --git a/src/net/sf/jremoterun/utilities/nonjdk/timer/WaitNotifyMethods.java b/src/net/sf/jremoterun/utilities/nonjdk/timer/WaitNotifyMethods.java index e8cfa52f..2c86ceb9 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/timer/WaitNotifyMethods.java +++ b/src/net/sf/jremoterun/utilities/nonjdk/timer/WaitNotifyMethods.java @@ -1,7 +1,12 @@ package net.sf.jremoterun.utilities.nonjdk.timer; +import groovy.transform.CompileStatic; + +@CompileStatic public class WaitNotifyMethods { + + public static void wait(final Object lock) throws InterruptedException { lock.wait(); } @@ -18,12 +23,6 @@ public static void notifyAll(final Object lock) { lock.notifyAll(); } - public static boolean isNull(Object object) { - return object == null; - } - public static void print(String msgs) { - System.out.println(msgs); - } } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/timer/WaitNotifyMethods2.java b/src/net/sf/jremoterun/utilities/nonjdk/timer/WaitNotifyMethods2.java new file mode 100644 index 00000000..ab083375 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/timer/WaitNotifyMethods2.java @@ -0,0 +1,28 @@ +package net.sf.jremoterun.utilities.nonjdk.timer; + +import groovy.transform.CompileStatic; + +@CompileStatic +public class WaitNotifyMethods2 { + + public Object lock = new Object(); + + + public void wait2() throws InterruptedException { + lock.wait(); + } + + public void wait2(final long timeout) throws InterruptedException { + lock.wait(timeout); + } + + public void notify2() { + lock.notify(); + } + + public void notifyAll2() { + lock.notifyAll(); + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/winutils/WinCmdUtils.groovy b/src/net/sf/jremoterun/utilities/nonjdk/winutils/WinCmdUtils.groovy index ba21b367..bb2ac5d0 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/winutils/WinCmdUtils.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/winutils/WinCmdUtils.groovy @@ -1,8 +1,9 @@ package net.sf.jremoterun.utilities.nonjdk.winutils +import com.github.tuupertunut.powershelllibjava.PowerShell import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.nonjdk.GeneralUtils +import net.sf.jremoterun.utilities.nonjdk.nativeprocess.NativeProcessResult import java.util.logging.Logger @@ -12,13 +13,81 @@ class WinCmdUtils { private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + static void stopService(String serviceName) { String cmd = " sc config ${serviceName} start= disabled" - GeneralUtils.runNativeProcess(cmd) + NativeProcessResult.runNativeProcessAndWait cmd cmd = " sc stop ${serviceName}" - GeneralUtils.runNativeProcess(cmd) + NativeProcessResult.runNativeProcessAndWait cmd + + } + + static void exportMountedDrives1(File exportFile) { + File parentFile = exportFile.getParentFile() + if (!parentFile.exists()) { + throw new FileNotFoundException("${parentFile}") + } + if (!exportFile.getName().endsWith('.reg')) { + throw new Exception("bad file extention ${exportFile}") + } + String cmd = "reg Export HKEY_CURRENT_USER\\Network ${exportFile.getCanonicalFile().getAbsolutePath()}" + NativeProcessResult.runNativeProcessAndWait cmd + } + /** + * https://superuser.com/questions/1105292/backup-mapped-drive-paths + */ + static void exportMountedDrives3(File exportFile) { + File parentFile = exportFile.getParentFile() + assert parentFile.exists() + exportFile.delete() + assert !exportFile.exists() + String cmd = exportcmd + exportFile.getAbsolutePath(); + PowerShell psSession = PowerShell.open(); + log.info psSession.executeCommands(createCommands(cmd)); + psSession.close() + if (!exportFile.exists()) { + throw new Exception("export failed with unknown reason : ${exportFile}") + } } + static String[] createCommands(String commands) { + List strings = commands.tokenize('\r\n') + strings = strings.collect { it.trim() } + strings = strings.findAll { !it.startsWith('#') } + return strings.toArray(new String[0]) + } + + + + public static String exportcmd = ''' +# Define array to hold identified mapped drives. +$mappedDrives = @() +# Get a list of the drives on the system, including only FileSystem type drives. +$drives = Get-PSDrive -PSProvider FileSystem + +# Iterate the drive list +foreach ($drive in $drives) { + # If the current drive has a DisplayRoot property, then it's a mapped drive. + if ($drive.DisplayRoot) { + # Exctract the drive's Name (the letter) and its DisplayRoot (the UNC path), and add then to the array. + $mappedDrives += Select-Object Name,DisplayRoot -InputObject $drive + } +} + +# Take array of mapped drives and export it to a CSV file. +$mappedDrives | Export-Csv '''; + + + private static String importCmd = ''' +# Import drive list. +$mappedDrives = Import-Csv mappedDrives.csv + +# Iterate over the drives in the list. +foreach ($drive in $mappedDrives) { + # Create a new mapped drive for this entry. + New-PSDrive -Name $drive.Name -PSProvider "FileSystem" -Root $drive.DisplayRoot -Persist -ErrorAction Continue +} +'''; } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/winutils/WinCmdUtils2.groovy b/src/net/sf/jremoterun/utilities/nonjdk/winutils/WinCmdUtils2.groovy index ec98d204..52be77f2 100644 --- a/src/net/sf/jremoterun/utilities/nonjdk/winutils/WinCmdUtils2.groovy +++ b/src/net/sf/jremoterun/utilities/nonjdk/winutils/WinCmdUtils2.groovy @@ -5,7 +5,7 @@ import com.sun.jna.platform.win32.User32 import com.sun.jna.platform.win32.WinDef import groovy.transform.CompileStatic import net.sf.jremoterun.utilities.JrrClassUtils -import net.sf.jremoterun.utilities.nonjdk.GeneralUtils +import net.sf.jremoterun.utilities.nonjdk.nativeprocess.NativeProcessResult import java.util.logging.Logger @@ -28,7 +28,7 @@ class WinCmdUtils2 { static void closeProcessSoft(ProcessUtils.ProcessInfo processId) { String cmd = "taskkill /PID ${processId.processId}" - GeneralUtils.runNativeProcess(cmd) + NativeProcessResult.runNativeProcessAndWait cmd log.info "close event sent for ${processId.processId} ${processId.imageName}" } diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ziputil/FileLineHandler.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ziputil/FileLineHandler.groovy new file mode 100644 index 00000000..4f51ad17 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ziputil/FileLineHandler.groovy @@ -0,0 +1,68 @@ +package net.sf.jremoterun.utilities.nonjdk.ziputil + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.nio.charset.Charset +import java.util.logging.Logger +import java.util.zip.GZIPInputStream + +/** + * TODO use + * @see org.apache.commons.compress.compressors.CompressorStreamFactory#createCompressorInputStream(java.lang.String, java.io.InputStream, boolean) + */ +@CompileStatic +abstract class FileLineHandler extends FileLineHandlerBase { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + FileLineHandler(File file) { + super(file) + } + + FileLineHandler(File file, LineHandlerSupport lineHandlerSupport) { + super(file, lineHandlerSupport) + } + + /** + * return true - will continue processing + * return false - need stop processing. + * + * Auto-detect EOF + */ + abstract boolean handleLine(String line) throws Exception; + + void onFinishedFine() { + + } + + void runHandleEachLine() { + openStream() + try { + while (true) { + String line = readNextLine(); + if (line == null) { + break; + } + try { + boolean needContinue = handleLine(line) + if (!needContinue) { + break; + } + } catch (Throwable e) { + onFailed(line, e) + } + } + onFinishedFine() + } finally { + onClose() + } + } + + void onFailed(String line, Throwable exception1) { + log.info("failed handle ${line} ${exception1}"); + throw exception1 + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ziputil/FileLineHandlerBase.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ziputil/FileLineHandlerBase.groovy new file mode 100644 index 00000000..7f3daea5 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ziputil/FileLineHandlerBase.groovy @@ -0,0 +1,85 @@ +package net.sf.jremoterun.utilities.nonjdk.ziputil + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.nio.charset.Charset +import java.util.logging.Logger + +/** + * TODO use + * @see org.apache.commons.compress.compressors.CompressorStreamFactory#createCompressorInputStream(java.lang.String, java.io.InputStream, boolean) + */ +@CompileStatic +abstract class FileLineHandlerBase { + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + public final File file; + public final LineHandlerSupport lineHandlerSupport + public InputStream inputStream; + public BufferedReader reader; + public int processedLines = 0; + public boolean autoClose = true; + public boolean reachedEof = false; + public boolean streamClosed = false; + + + FileLineHandlerBase(File file) { + this.file = file + if (file.getName().endsWith('.gz')) { + lineHandlerSupport = new GzipLineHandlerSupport(file) + } else { + lineHandlerSupport = new StdLineHandlerSupport(file) + } + } + + FileLineHandlerBase(File file, LineHandlerSupport lineHandlerSupport) { + this.file = file + this.lineHandlerSupport = lineHandlerSupport + } + + + String readNextLine() throws IOException{ + if (reader == null) { + openStream() + } + String line = reader.readLine(); + if (line == null) { + reachedEof = true; + if (autoClose) { + onClose() + } + return null + } + processedLines++; + return line + } + + + void onClose() throws IOException { + if (!streamClosed) { + try { + lineHandlerSupport.closeStream() + streamClosed = true + } catch (Throwable e) { + onCloseException(e); + } + } + } + + void onCloseException(Throwable e) { + throw e; + } + + + void openStream() { + inputStream = lineHandlerSupport.openStream() + reader = new BufferedReader(new InputStreamReader(inputStream, getCharset())); + } + + String getCharset() { + return Charset.defaultCharset() + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ziputil/GzipLineHandlerSupport.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ziputil/GzipLineHandlerSupport.groovy new file mode 100644 index 00000000..5f2bd830 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ziputil/GzipLineHandlerSupport.groovy @@ -0,0 +1,39 @@ +package net.sf.jremoterun.utilities.nonjdk.ziputil + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.nio.charset.Charset; +import java.util.logging.Logger +import java.util.zip.GZIPInputStream; + +@CompileStatic +class GzipLineHandlerSupport implements LineHandlerSupport{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + + public File file; + public BufferedInputStream bufferedInputStream; + + public GZIPInputStream gzipInputStream; + + + public GzipLineHandlerSupport(File file) { + this.file = file + } + + + + void closeStream(){ + bufferedInputStream.close() + } + + + InputStream openStream() { + bufferedInputStream = file.newInputStream() + gzipInputStream = new GZIPInputStream(bufferedInputStream) + } + + +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ziputil/LineHandlerSupport.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ziputil/LineHandlerSupport.groovy new file mode 100644 index 00000000..b8eca105 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ziputil/LineHandlerSupport.groovy @@ -0,0 +1,14 @@ +package net.sf.jremoterun.utilities.nonjdk.ziputil + +import groovy.transform.CompileStatic; +import net.sf.jremoterun.utilities.JrrClassUtils; +import java.util.logging.Logger; + +@CompileStatic +interface LineHandlerSupport { + + void closeStream() throws IOException; + + + InputStream openStream() throws IOException; +} diff --git a/src/net/sf/jremoterun/utilities/nonjdk/ziputil/StdLineHandlerSupport.groovy b/src/net/sf/jremoterun/utilities/nonjdk/ziputil/StdLineHandlerSupport.groovy new file mode 100644 index 00000000..a35167e6 --- /dev/null +++ b/src/net/sf/jremoterun/utilities/nonjdk/ziputil/StdLineHandlerSupport.groovy @@ -0,0 +1,35 @@ +package net.sf.jremoterun.utilities.nonjdk.ziputil + +import groovy.transform.CompileStatic +import net.sf.jremoterun.utilities.JrrClassUtils + +import java.nio.charset.Charset +import java.util.logging.Logger +import java.util.zip.GZIPInputStream + +@CompileStatic +class StdLineHandlerSupport implements LineHandlerSupport{ + private static final Logger log = JrrClassUtils.getJdkLogForCurrentClass(); + + + + public File file; + public BufferedInputStream bufferedInputStream; + + + StdLineHandlerSupport(File file) { + this.file = file + } + + + + void closeStream(){ + bufferedInputStream.close() + } + + + InputStream openStream() { + bufferedInputStream = file.newInputStream() + } + +} diff --git a/src/net/sf/jremoterun/utilities/swingfind/SwingComponentFinder.groovy b/src/net/sf/jremoterun/utilities/swingfind/SwingComponentFinder.groovy index 33263168..2a4582c8 100644 --- a/src/net/sf/jremoterun/utilities/swingfind/SwingComponentFinder.groovy +++ b/src/net/sf/jremoterun/utilities/swingfind/SwingComponentFinder.groovy @@ -61,8 +61,8 @@ public class SwingComponentFinder { } } } else if (component instanceof Container) { - Container new_name = (Container) component; - Component aa = findComponent(new_name, accepter); + Container nestedContainer = (Container) component; + Component aa = findComponent(nestedContainer, accepter); if (aa != null) { return aa; } diff --git a/test/timmoson/test/DiffClassloaderServiceRegister.java b/test/timmoson/test/DiffClassloaderServiceRegister.java index 0018fab7..b3ff5163 100644 --- a/test/timmoson/test/DiffClassloaderServiceRegister.java +++ b/test/timmoson/test/DiffClassloaderServiceRegister.java @@ -8,13 +8,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.reflect.Reflection; import timmoson.server.ServiceLocator; import timmoson.testservice.SampleService; public class DiffClassloaderServiceRegister implements ICodeForExecuting { - private static final Log log = LogFactory.getLog(Reflection - .getCallerClass(1)); + private static final Log log = LogFactory.getLog(DiffClassloaderServiceRegister.class); @Override public Object run(List params, Map previousCode) throws Exception {