p2p u5 started, todos mark things to be done
This commit is contained in:
parent
bb754856ac
commit
6c496655ef
74
ws2012/P2P/uebungen/11/build.xml
Normal file
74
ws2012/P2P/uebungen/11/build.xml
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="p2p_u5" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project p2p_u5.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar-with-manifest: JAR building (if you are using a manifest)
|
||||
-do-jar-without-manifest: JAR building (if you are not using a manifest)
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="p2p_u5-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
7
ws2012/P2P/uebungen/11/logging.properties
Normal file
7
ws2012/P2P/uebungen/11/logging.properties
Normal file
@ -0,0 +1,7 @@
|
||||
handlers=java.util.logging.ConsoleHandler
|
||||
|
||||
.level=FINEST
|
||||
|
||||
java.util.logging.SimpleFormatter.format=[%1$tF %1$tr] %3$s %4$s: %5$s %n
|
||||
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
|
||||
java.util.logging.ConsoleHandler.level = FINEST
|
||||
3
ws2012/P2P/uebungen/11/manifest.mf
Normal file
3
ws2012/P2P/uebungen/11/manifest.mf
Normal file
@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
||||
924
ws2012/P2P/uebungen/11/nbproject/build-impl.xml
Normal file
924
ws2012/P2P/uebungen/11/nbproject/build-impl.xml
Normal file
@ -0,0 +1,924 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
*** GENERATED FROM project.xml - DO NOT EDIT ***
|
||||
*** EDIT ../build.xml INSTEAD ***
|
||||
|
||||
For the purpose of easier reading the script
|
||||
is divided into following sections:
|
||||
|
||||
- initialization
|
||||
- compilation
|
||||
- jar
|
||||
- execution
|
||||
- debugging
|
||||
- javadoc
|
||||
- junit compilation
|
||||
- junit execution
|
||||
- junit debugging
|
||||
- applet
|
||||
- cleanup
|
||||
|
||||
-->
|
||||
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="p2p_u5-impl">
|
||||
<fail message="Please build using Ant 1.7.1 or higher.">
|
||||
<condition>
|
||||
<not>
|
||||
<antversion atleast="1.7.1"/>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
|
||||
<!--
|
||||
======================
|
||||
INITIALIZATION SECTION
|
||||
======================
|
||||
-->
|
||||
<target name="-pre-init">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="-pre-init" name="-init-private">
|
||||
<property file="nbproject/private/config.properties"/>
|
||||
<property file="nbproject/private/configs/${config}.properties"/>
|
||||
<property file="nbproject/private/private.properties"/>
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private" name="-init-user">
|
||||
<property file="${user.properties.file}"/>
|
||||
<!-- The two properties below are usually overridden -->
|
||||
<!-- by the active platform. Just a fallback. -->
|
||||
<property name="default.javac.source" value="1.4"/>
|
||||
<property name="default.javac.target" value="1.4"/>
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private,-init-user" name="-init-project">
|
||||
<property file="nbproject/configs/${config}.properties"/>
|
||||
<property file="nbproject/project.properties"/>
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
|
||||
<j2seproject1:property name="platform.home" value="platforms.${platform.active}.home"/>
|
||||
<j2seproject1:property name="platform.bootcp" value="platforms.${platform.active}.bootclasspath"/>
|
||||
<j2seproject1:property name="platform.compiler" value="platforms.${platform.active}.compile"/>
|
||||
<j2seproject1:property name="platform.javac.tmp" value="platforms.${platform.active}.javac"/>
|
||||
<condition property="platform.javac" value="${platform.home}/bin/javac">
|
||||
<equals arg1="${platform.javac.tmp}" arg2="$${platforms.${platform.active}.javac}"/>
|
||||
</condition>
|
||||
<property name="platform.javac" value="${platform.javac.tmp}"/>
|
||||
<j2seproject1:property name="platform.java.tmp" value="platforms.${platform.active}.java"/>
|
||||
<condition property="platform.java" value="${platform.home}/bin/java">
|
||||
<equals arg1="${platform.java.tmp}" arg2="$${platforms.${platform.active}.java}"/>
|
||||
</condition>
|
||||
<property name="platform.java" value="${platform.java.tmp}"/>
|
||||
<j2seproject1:property name="platform.javadoc.tmp" value="platforms.${platform.active}.javadoc"/>
|
||||
<condition property="platform.javadoc" value="${platform.home}/bin/javadoc">
|
||||
<equals arg1="${platform.javadoc.tmp}" arg2="$${platforms.${platform.active}.javadoc}"/>
|
||||
</condition>
|
||||
<property name="platform.javadoc" value="${platform.javadoc.tmp}"/>
|
||||
<condition property="platform.invalid" value="true">
|
||||
<or>
|
||||
<contains string="${platform.javac}" substring="$${platforms."/>
|
||||
<contains string="${platform.java}" substring="$${platforms."/>
|
||||
<contains string="${platform.javadoc}" substring="$${platforms."/>
|
||||
</or>
|
||||
</condition>
|
||||
<fail unless="platform.home">Must set platform.home</fail>
|
||||
<fail unless="platform.bootcp">Must set platform.bootcp</fail>
|
||||
<fail unless="platform.java">Must set platform.java</fail>
|
||||
<fail unless="platform.javac">Must set platform.javac</fail>
|
||||
<fail if="platform.invalid">
|
||||
The J2SE Platform is not correctly set up.
|
||||
Your active platform is: ${platform.active}, but the corresponding property "platforms.${platform.active}.home" is not found in the project's properties files.
|
||||
Either open the project in the IDE and setup the Platform with the same name or add it manually.
|
||||
For example like this:
|
||||
ant -Duser.properties.file=<path_to_property_file> jar (where you put the property "platforms.${platform.active}.home" in a .properties file)
|
||||
or ant -Dplatforms.${platform.active}.home=<path_to_JDK_home> jar (where no properties file is used)
|
||||
</fail>
|
||||
<available file="${manifest.file}" property="manifest.available"/>
|
||||
<available file="${application.splash}" property="splashscreen.available"/>
|
||||
<condition property="main.class.available">
|
||||
<and>
|
||||
<isset property="main.class"/>
|
||||
<not>
|
||||
<equals arg1="${main.class}" arg2="" trim="true"/>
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="manifest.available+main.class">
|
||||
<and>
|
||||
<isset property="manifest.available"/>
|
||||
<isset property="main.class.available"/>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="do.mkdist">
|
||||
<and>
|
||||
<isset property="libs.CopyLibs.classpath"/>
|
||||
<not>
|
||||
<istrue value="${mkdist.disabled}"/>
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="manifest.available+main.class+mkdist.available">
|
||||
<and>
|
||||
<istrue value="${manifest.available+main.class}"/>
|
||||
<isset property="do.mkdist"/>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="manifest.available+main.class+mkdist.available+splashscreen.available">
|
||||
<and>
|
||||
<istrue value="${manifest.available+main.class+mkdist.available}"/>
|
||||
<istrue value="${splashscreen.available}"/>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="do.archive">
|
||||
<not>
|
||||
<istrue value="${jar.archive.disabled}"/>
|
||||
</not>
|
||||
</condition>
|
||||
<condition property="do.archive+manifest.available">
|
||||
<and>
|
||||
<isset property="manifest.available"/>
|
||||
<istrue value="${do.archive}"/>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="do.archive+manifest.available+main.class">
|
||||
<and>
|
||||
<istrue value="${manifest.available+main.class}"/>
|
||||
<istrue value="${do.archive}"/>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="do.archive+manifest.available+main.class+mkdist.available">
|
||||
<and>
|
||||
<istrue value="${manifest.available+main.class+mkdist.available}"/>
|
||||
<istrue value="${do.archive}"/>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="do.archive+manifest.available+main.class+mkdist.available+splashscreen.available">
|
||||
<and>
|
||||
<istrue value="${manifest.available+main.class+mkdist.available+splashscreen.available}"/>
|
||||
<istrue value="${do.archive}"/>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="have.tests">
|
||||
<or/>
|
||||
</condition>
|
||||
<condition property="have.sources">
|
||||
<or>
|
||||
<available file="${src.dir}"/>
|
||||
</or>
|
||||
</condition>
|
||||
<condition property="netbeans.home+have.tests">
|
||||
<and>
|
||||
<isset property="netbeans.home"/>
|
||||
<isset property="have.tests"/>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="no.javadoc.preview">
|
||||
<and>
|
||||
<isset property="javadoc.preview"/>
|
||||
<isfalse value="${javadoc.preview}"/>
|
||||
</and>
|
||||
</condition>
|
||||
<property name="run.jvmargs" value=""/>
|
||||
<property name="javac.compilerargs" value=""/>
|
||||
<property name="work.dir" value="${basedir}"/>
|
||||
<condition property="no.deps">
|
||||
<and>
|
||||
<istrue value="${no.dependencies}"/>
|
||||
</and>
|
||||
</condition>
|
||||
<property name="javac.debug" value="true"/>
|
||||
<property name="javadoc.preview" value="true"/>
|
||||
<property name="application.args" value=""/>
|
||||
<property name="source.encoding" value="${file.encoding}"/>
|
||||
<property name="runtime.encoding" value="${source.encoding}"/>
|
||||
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
|
||||
<and>
|
||||
<isset property="javadoc.encoding"/>
|
||||
<not>
|
||||
<equals arg1="${javadoc.encoding}" arg2=""/>
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
<property name="javadoc.encoding.used" value="${source.encoding}"/>
|
||||
<property name="includes" value="**"/>
|
||||
<property name="excludes" value=""/>
|
||||
<property name="do.depend" value="false"/>
|
||||
<condition property="do.depend.true">
|
||||
<istrue value="${do.depend}"/>
|
||||
</condition>
|
||||
<path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
|
||||
<condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
|
||||
<length length="0" string="${endorsed.classpath}" when="greater"/>
|
||||
</condition>
|
||||
<property name="jar.index" value="false"/>
|
||||
<available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
|
||||
</target>
|
||||
<target name="-post-init">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
|
||||
<fail unless="src.dir">Must set src.dir</fail>
|
||||
<fail unless="build.dir">Must set build.dir</fail>
|
||||
<fail unless="dist.dir">Must set dist.dir</fail>
|
||||
<fail unless="build.classes.dir">Must set build.classes.dir</fail>
|
||||
<fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
|
||||
<fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
|
||||
<fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
|
||||
<fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
|
||||
<fail unless="dist.jar">Must set dist.jar</fail>
|
||||
</target>
|
||||
<target name="-init-macrodef-property">
|
||||
<macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||
<attribute name="name"/>
|
||||
<attribute name="value"/>
|
||||
<sequential>
|
||||
<property name="@{name}" value="${@{value}}"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
|
||||
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${src.dir}" name="srcdir"/>
|
||||
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||
<attribute default="${javac.classpath}" name="classpath"/>
|
||||
<attribute default="${javac.processorpath}" name="processorpath"/>
|
||||
<attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
|
||||
<attribute default="${includes}" name="includes"/>
|
||||
<attribute default="${excludes}" name="excludes"/>
|
||||
<attribute default="${javac.debug}" name="debug"/>
|
||||
<attribute default="${empty.dir}" name="sourcepath"/>
|
||||
<attribute default="${empty.dir}" name="gensrcdir"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<property location="${build.dir}/empty" name="empty.dir"/>
|
||||
<mkdir dir="${empty.dir}"/>
|
||||
<mkdir dir="@{apgeneratedsrcdir}"/>
|
||||
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" executable="${platform.javac}" fork="yes" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
|
||||
<src>
|
||||
<dirset dir="@{gensrcdir}" erroronmissingdir="false">
|
||||
<include name="*"/>
|
||||
</dirset>
|
||||
</src>
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
<compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<compilerarg line="${javac.compilerargs}"/>
|
||||
<compilerarg value="-processorpath"/>
|
||||
<compilerarg path="@{processorpath}:${empty.dir}"/>
|
||||
<compilerarg line="${ap.processors.internal}"/>
|
||||
<compilerarg line="${annotation.processing.processor.options}"/>
|
||||
<compilerarg value="-s"/>
|
||||
<compilerarg path="@{apgeneratedsrcdir}"/>
|
||||
<compilerarg line="${ap.proc.none.internal}"/>
|
||||
<customize/>
|
||||
</javac>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
|
||||
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${src.dir}" name="srcdir"/>
|
||||
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||
<attribute default="${javac.classpath}" name="classpath"/>
|
||||
<attribute default="${javac.processorpath}" name="processorpath"/>
|
||||
<attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
|
||||
<attribute default="${includes}" name="includes"/>
|
||||
<attribute default="${excludes}" name="excludes"/>
|
||||
<attribute default="${javac.debug}" name="debug"/>
|
||||
<attribute default="${empty.dir}" name="sourcepath"/>
|
||||
<attribute default="${empty.dir}" name="gensrcdir"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<property location="${build.dir}/empty" name="empty.dir"/>
|
||||
<mkdir dir="${empty.dir}"/>
|
||||
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" executable="${platform.javac}" fork="yes" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
|
||||
<src>
|
||||
<dirset dir="@{gensrcdir}" erroronmissingdir="false">
|
||||
<include name="*"/>
|
||||
</dirset>
|
||||
</src>
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
<compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<compilerarg line="${javac.compilerargs}"/>
|
||||
<customize/>
|
||||
</javac>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
|
||||
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${src.dir}" name="srcdir"/>
|
||||
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||
<attribute default="${javac.classpath}" name="classpath"/>
|
||||
<sequential>
|
||||
<depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
</depend>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
<macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||
<sequential>
|
||||
<fail unless="javac.includes">Must set javac.includes</fail>
|
||||
<pathconvert pathsep="${line.separator}" property="javac.includes.binary">
|
||||
<path>
|
||||
<filelist dir="@{destdir}" files="${javac.includes}"/>
|
||||
</path>
|
||||
<globmapper from="*.java" to="*.class"/>
|
||||
</pathconvert>
|
||||
<tempfile deleteonexit="true" property="javac.includesfile.binary"/>
|
||||
<echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
|
||||
<delete>
|
||||
<files includesfile="${javac.includesfile.binary}"/>
|
||||
</delete>
|
||||
<delete file="${javac.includesfile.binary}"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target name="-init-macrodef-junit">
|
||||
<macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${includes}" name="includes"/>
|
||||
<attribute default="${excludes}" name="excludes"/>
|
||||
<attribute default="**" name="testincludes"/>
|
||||
<sequential>
|
||||
<junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}">
|
||||
<batchtest todir="${build.test.results.dir}"/>
|
||||
<classpath>
|
||||
<path path="${run.test.classpath}"/>
|
||||
</classpath>
|
||||
<syspropertyset>
|
||||
<propertyref prefix="test-sys-prop."/>
|
||||
<mapper from="test-sys-prop.*" to="*" type="glob"/>
|
||||
</syspropertyset>
|
||||
<formatter type="brief" usefile="false"/>
|
||||
<formatter type="xml"/>
|
||||
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<jvmarg line="${run.jvmargs}"/>
|
||||
</junit>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target depends="-init-debug-args" name="-init-macrodef-nbjpda">
|
||||
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||
<attribute default="${main.class}" name="name"/>
|
||||
<attribute default="${debug.classpath}" name="classpath"/>
|
||||
<attribute default="" name="stopclassname"/>
|
||||
<sequential>
|
||||
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
<bootclasspath>
|
||||
<path path="${platform.bootcp}"/>
|
||||
</bootclasspath>
|
||||
</nbjpdastart>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
<macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||
<attribute default="${build.classes.dir}" name="dir"/>
|
||||
<sequential>
|
||||
<nbjpdareload>
|
||||
<fileset dir="@{dir}" includes="${fix.classes}">
|
||||
<include name="${fix.includes}*.class"/>
|
||||
</fileset>
|
||||
</nbjpdareload>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target name="-init-debug-args">
|
||||
<exec executable="${platform.java}" outputproperty="version-output">
|
||||
<arg value="-version"/>
|
||||
</exec>
|
||||
<condition property="have-jdk-older-than-1.4">
|
||||
<or>
|
||||
<contains string="${version-output}" substring="java version "1.0"/>
|
||||
<contains string="${version-output}" substring="java version "1.1"/>
|
||||
<contains string="${version-output}" substring="java version "1.2"/>
|
||||
<contains string="${version-output}" substring="java version "1.3"/>
|
||||
</or>
|
||||
</condition>
|
||||
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
|
||||
<istrue value="${have-jdk-older-than-1.4}"/>
|
||||
</condition>
|
||||
<condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
|
||||
<os family="windows"/>
|
||||
</condition>
|
||||
<condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
|
||||
<isset property="debug.transport"/>
|
||||
</condition>
|
||||
</target>
|
||||
<target depends="-init-debug-args" name="-init-macrodef-debug">
|
||||
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${main.class}" name="classname"/>
|
||||
<attribute default="${debug.classpath}" name="classpath"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<java classname="@{classname}" dir="${work.dir}" fork="true" jvm="${platform.java}">
|
||||
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<jvmarg line="${debug-args-line}"/>
|
||||
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
|
||||
<jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
|
||||
<redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
|
||||
<jvmarg line="${run.jvmargs}"/>
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
<syspropertyset>
|
||||
<propertyref prefix="run-sys-prop."/>
|
||||
<mapper from="run-sys-prop.*" to="*" type="glob"/>
|
||||
</syspropertyset>
|
||||
<customize/>
|
||||
</java>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target name="-init-macrodef-java">
|
||||
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||
<attribute default="${main.class}" name="classname"/>
|
||||
<attribute default="${run.classpath}" name="classpath"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<java classname="@{classname}" dir="${work.dir}" fork="true" jvm="${platform.java}">
|
||||
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
|
||||
<jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
|
||||
<redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
|
||||
<jvmarg line="${run.jvmargs}"/>
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
<syspropertyset>
|
||||
<propertyref prefix="run-sys-prop."/>
|
||||
<mapper from="run-sys-prop.*" to="*" type="glob"/>
|
||||
</syspropertyset>
|
||||
<customize/>
|
||||
</java>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target name="-init-macrodef-copylibs">
|
||||
<macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||
<pathconvert property="run.classpath.without.build.classes.dir">
|
||||
<path path="${run.classpath}"/>
|
||||
<map from="${build.classes.dir.resolved}" to=""/>
|
||||
</pathconvert>
|
||||
<pathconvert pathsep=" " property="jar.classpath">
|
||||
<path path="${run.classpath.without.build.classes.dir}"/>
|
||||
<chainedmapper>
|
||||
<flattenmapper/>
|
||||
<globmapper from="*" to="lib/*"/>
|
||||
</chainedmapper>
|
||||
</pathconvert>
|
||||
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
|
||||
<copylibs compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="${jar.classpath}"/>
|
||||
<customize/>
|
||||
</manifest>
|
||||
</copylibs>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target name="-init-presetdef-jar">
|
||||
<presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||
<jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">
|
||||
<j2seproject1:fileset dir="${build.classes.dir}"/>
|
||||
</jar>
|
||||
</presetdef>
|
||||
</target>
|
||||
<target name="-init-ap-cmdline-properties">
|
||||
<property name="annotation.processing.enabled" value="true"/>
|
||||
<property name="annotation.processing.processors.list" value=""/>
|
||||
<property name="annotation.processing.processor.options" value=""/>
|
||||
<property name="annotation.processing.run.all.processors" value="true"/>
|
||||
<property name="javac.processorpath" value="${javac.classpath}"/>
|
||||
<property name="javac.test.processorpath" value="${javac.test.classpath}"/>
|
||||
<condition property="ap.supported.internal" value="true">
|
||||
<not>
|
||||
<matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
|
||||
</not>
|
||||
</condition>
|
||||
</target>
|
||||
<target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
|
||||
<condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
|
||||
<isfalse value="${annotation.processing.run.all.processors}"/>
|
||||
</condition>
|
||||
<condition else="" property="ap.proc.none.internal" value="-proc:none">
|
||||
<isfalse value="${annotation.processing.enabled}"/>
|
||||
</condition>
|
||||
</target>
|
||||
<target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
|
||||
<property name="ap.cmd.line.internal" value=""/>
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
|
||||
<!--
|
||||
===================
|
||||
COMPILATION SECTION
|
||||
===================
|
||||
-->
|
||||
<target name="-deps-jar-init" unless="built-jar.properties">
|
||||
<property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
|
||||
<delete file="${built-jar.properties}" quiet="true"/>
|
||||
</target>
|
||||
<target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
|
||||
<echo level="warn" message="Cycle detected: p2p_u5 was already built"/>
|
||||
</target>
|
||||
<target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
|
||||
<mkdir dir="${build.dir}"/>
|
||||
<touch file="${built-jar.properties}" verbose="false"/>
|
||||
<property file="${built-jar.properties}" prefix="already.built.jar."/>
|
||||
<antcall target="-warn-already-built-jar"/>
|
||||
<propertyfile file="${built-jar.properties}">
|
||||
<entry key="${basedir}" value=""/>
|
||||
</propertyfile>
|
||||
</target>
|
||||
<target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
|
||||
<target depends="init" name="-check-automatic-build">
|
||||
<available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
|
||||
</target>
|
||||
<target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
|
||||
<antcall target="clean"/>
|
||||
</target>
|
||||
<target depends="init,deps-jar" name="-pre-pre-compile">
|
||||
<mkdir dir="${build.classes.dir}"/>
|
||||
</target>
|
||||
<target name="-pre-compile">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target if="do.depend.true" name="-compile-depend">
|
||||
<pathconvert property="build.generated.subdirs">
|
||||
<dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||
<include name="*"/>
|
||||
</dirset>
|
||||
</pathconvert>
|
||||
<j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
|
||||
</target>
|
||||
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
|
||||
<j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
|
||||
<copy todir="${build.classes.dir}">
|
||||
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||
</copy>
|
||||
</target>
|
||||
<target if="has.persistence.xml" name="-copy-persistence-xml">
|
||||
<mkdir dir="${build.classes.dir}/META-INF"/>
|
||||
<copy todir="${build.classes.dir}/META-INF">
|
||||
<fileset dir="${meta.inf.dir}" includes="persistence.xml"/>
|
||||
</copy>
|
||||
</target>
|
||||
<target name="-post-compile">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
|
||||
<target name="-pre-compile-single">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
|
||||
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
||||
<j2seproject3:force-recompile/>
|
||||
<j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
|
||||
</target>
|
||||
<target name="-post-compile-single">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
|
||||
<!--
|
||||
====================
|
||||
JAR BUILDING SECTION
|
||||
====================
|
||||
-->
|
||||
<target depends="init" name="-pre-pre-jar">
|
||||
<dirname file="${dist.jar}" property="dist.jar.dir"/>
|
||||
<mkdir dir="${dist.jar.dir}"/>
|
||||
</target>
|
||||
<target name="-pre-jar">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive" name="-do-jar-without-manifest" unless="manifest.available">
|
||||
<j2seproject1:jar/>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
|
||||
<j2seproject1:jar manifest="${manifest.file}"/>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
|
||||
<j2seproject1:jar manifest="${manifest.file}">
|
||||
<j2seproject1:manifest>
|
||||
<j2seproject1:attribute name="Main-Class" value="${main.class}"/>
|
||||
</j2seproject1:manifest>
|
||||
</j2seproject1:jar>
|
||||
<echo>To run this application from the command line without Ant, try:</echo>
|
||||
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
||||
<pathconvert property="run.classpath.with.dist.jar">
|
||||
<path path="${run.classpath}"/>
|
||||
<map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
|
||||
</pathconvert>
|
||||
<echo>${platform.java} -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar,-init-macrodef-copylibs" if="do.archive+manifest.available+main.class+mkdist.available+splashscreen.available" name="-do-jar-with-libraries-and-splashscreen">
|
||||
<basename file="${application.splash}" property="splashscreen.basename"/>
|
||||
<mkdir dir="${build.classes.dir}/META-INF"/>
|
||||
<copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
|
||||
<j2seproject3:copylibs>
|
||||
<customize>
|
||||
<attribute name="Main-Class" value="${main.class}"/>
|
||||
<attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
|
||||
</customize>
|
||||
</j2seproject3:copylibs>
|
||||
<echo>To run this application from the command line without Ant, try:</echo>
|
||||
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
||||
<echo>${platform.java} -jar "${dist.jar.resolved}"</echo>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar,-init-macrodef-copylibs" if="do.archive+manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries" unless="splashscreen.available">
|
||||
<j2seproject3:copylibs>
|
||||
<customize>
|
||||
<attribute name="Main-Class" value="${main.class}"/>
|
||||
</customize>
|
||||
</j2seproject3:copylibs>
|
||||
<echo>To run this application from the command line without Ant, try:</echo>
|
||||
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
||||
<echo>${platform.java} -jar "${dist.jar.resolved}"</echo>
|
||||
</target>
|
||||
<target name="-post-jar">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries-and-splashscreen,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
|
||||
<!--
|
||||
=================
|
||||
EXECUTION SECTION
|
||||
=================
|
||||
-->
|
||||
<target depends="init,compile" description="Run a main class." name="run">
|
||||
<j2seproject1:java>
|
||||
<customize>
|
||||
<arg line="${application.args}"/>
|
||||
</customize>
|
||||
</j2seproject1:java>
|
||||
</target>
|
||||
<target name="-do-not-recompile">
|
||||
<property name="javac.includes.binary" value=""/>
|
||||
</target>
|
||||
<target depends="init,compile-single" name="run-single">
|
||||
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
|
||||
<j2seproject1:java classname="${run.class}"/>
|
||||
</target>
|
||||
<target depends="init,compile-test-single" name="run-test-with-main">
|
||||
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
|
||||
<j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
|
||||
</target>
|
||||
<!--
|
||||
=================
|
||||
DEBUGGING SECTION
|
||||
=================
|
||||
-->
|
||||
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
|
||||
<j2seproject1:nbjpdastart name="${debug.class}"/>
|
||||
</target>
|
||||
<target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
|
||||
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
|
||||
</target>
|
||||
<target depends="init,compile" name="-debug-start-debuggee">
|
||||
<j2seproject3:debug>
|
||||
<customize>
|
||||
<arg line="${application.args}"/>
|
||||
</customize>
|
||||
</j2seproject3:debug>
|
||||
</target>
|
||||
<target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
|
||||
<target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
|
||||
<j2seproject1:nbjpdastart stopclassname="${main.class}"/>
|
||||
</target>
|
||||
<target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
|
||||
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
|
||||
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
|
||||
<j2seproject3:debug classname="${debug.class}"/>
|
||||
</target>
|
||||
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
|
||||
<target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
|
||||
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
|
||||
<j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
|
||||
</target>
|
||||
<target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
|
||||
<target depends="init" name="-pre-debug-fix">
|
||||
<fail unless="fix.includes">Must set fix.includes</fail>
|
||||
<property name="javac.includes" value="${fix.includes}.java"/>
|
||||
</target>
|
||||
<target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
|
||||
<j2seproject1:nbjpdareload/>
|
||||
</target>
|
||||
<target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
|
||||
<!--
|
||||
===============
|
||||
JAVADOC SECTION
|
||||
===============
|
||||
-->
|
||||
<target depends="init" if="have.sources" name="-javadoc-build">
|
||||
<mkdir dir="${dist.javadoc.dir}"/>
|
||||
<javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" executable="${platform.javadoc}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
|
||||
<classpath>
|
||||
<path path="${javac.classpath}"/>
|
||||
</classpath>
|
||||
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
|
||||
<filename name="**/*.java"/>
|
||||
</fileset>
|
||||
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||
<include name="**/*.java"/>
|
||||
</fileset>
|
||||
</javadoc>
|
||||
<copy todir="${dist.javadoc.dir}">
|
||||
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
|
||||
<filename name="**/doc-files/**"/>
|
||||
</fileset>
|
||||
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||
<include name="**/doc-files/**"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
|
||||
<nbbrowse file="${dist.javadoc.dir}/index.html"/>
|
||||
</target>
|
||||
<target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
|
||||
<!--
|
||||
=========================
|
||||
JUNIT COMPILATION SECTION
|
||||
=========================
|
||||
-->
|
||||
<target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
|
||||
<mkdir dir="${build.test.classes.dir}"/>
|
||||
</target>
|
||||
<target name="-pre-compile-test">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target if="do.depend.true" name="-compile-test-depend">
|
||||
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir=""/>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
|
||||
<j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir=""/>
|
||||
<copy todir="${build.test.classes.dir}"/>
|
||||
</target>
|
||||
<target name="-post-compile-test">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
|
||||
<target name="-pre-compile-test-single">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
|
||||
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
||||
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
|
||||
<j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="" srcdir=""/>
|
||||
<copy todir="${build.test.classes.dir}"/>
|
||||
</target>
|
||||
<target name="-post-compile-test-single">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
|
||||
<!--
|
||||
=======================
|
||||
JUNIT EXECUTION SECTION
|
||||
=======================
|
||||
-->
|
||||
<target depends="init" if="have.tests" name="-pre-test-run">
|
||||
<mkdir dir="${build.test.results.dir}"/>
|
||||
</target>
|
||||
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
|
||||
<j2seproject3:junit testincludes="**/*Test.java"/>
|
||||
</target>
|
||||
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
|
||||
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
|
||||
</target>
|
||||
<target depends="init" if="have.tests" name="test-report"/>
|
||||
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
|
||||
<target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
|
||||
<target depends="init" if="have.tests" name="-pre-test-run-single">
|
||||
<mkdir dir="${build.test.results.dir}"/>
|
||||
</target>
|
||||
<target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
|
||||
<fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
|
||||
<j2seproject3:junit excludes="" includes="${test.includes}"/>
|
||||
</target>
|
||||
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
|
||||
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
|
||||
</target>
|
||||
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
|
||||
<!--
|
||||
=======================
|
||||
JUNIT DEBUGGING SECTION
|
||||
=======================
|
||||
-->
|
||||
<target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
|
||||
<fail unless="test.class">Must select one file in the IDE or set test.class</fail>
|
||||
<property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
|
||||
<delete file="${test.report.file}"/>
|
||||
<mkdir dir="${build.test.results.dir}"/>
|
||||
<j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
|
||||
<customize>
|
||||
<syspropertyset>
|
||||
<propertyref prefix="test-sys-prop."/>
|
||||
<mapper from="test-sys-prop.*" to="*" type="glob"/>
|
||||
</syspropertyset>
|
||||
<arg value="${test.class}"/>
|
||||
<arg value="showoutput=true"/>
|
||||
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
|
||||
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
|
||||
</customize>
|
||||
</j2seproject3:debug>
|
||||
</target>
|
||||
<target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
|
||||
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
|
||||
</target>
|
||||
<target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
|
||||
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
|
||||
<j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
|
||||
</target>
|
||||
<target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
|
||||
<!--
|
||||
=========================
|
||||
APPLET EXECUTION SECTION
|
||||
=========================
|
||||
-->
|
||||
<target depends="init,compile-single" name="run-applet">
|
||||
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
|
||||
<j2seproject1:java classname="sun.applet.AppletViewer">
|
||||
<customize>
|
||||
<arg value="${applet.url}"/>
|
||||
</customize>
|
||||
</j2seproject1:java>
|
||||
</target>
|
||||
<!--
|
||||
=========================
|
||||
APPLET DEBUGGING SECTION
|
||||
=========================
|
||||
-->
|
||||
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
|
||||
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
|
||||
<j2seproject3:debug classname="sun.applet.AppletViewer">
|
||||
<customize>
|
||||
<arg value="${applet.url}"/>
|
||||
</customize>
|
||||
</j2seproject3:debug>
|
||||
</target>
|
||||
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
|
||||
<!--
|
||||
===============
|
||||
CLEANUP SECTION
|
||||
===============
|
||||
-->
|
||||
<target name="-deps-clean-init" unless="built-clean.properties">
|
||||
<property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
|
||||
<delete file="${built-clean.properties}" quiet="true"/>
|
||||
</target>
|
||||
<target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
|
||||
<echo level="warn" message="Cycle detected: p2p_u5 was already built"/>
|
||||
</target>
|
||||
<target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
|
||||
<mkdir dir="${build.dir}"/>
|
||||
<touch file="${built-clean.properties}" verbose="false"/>
|
||||
<property file="${built-clean.properties}" prefix="already.built.clean."/>
|
||||
<antcall target="-warn-already-built-clean"/>
|
||||
<propertyfile file="${built-clean.properties}">
|
||||
<entry key="${basedir}" value=""/>
|
||||
</propertyfile>
|
||||
</target>
|
||||
<target depends="init" name="-do-clean">
|
||||
<delete dir="${build.dir}"/>
|
||||
<delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
|
||||
</target>
|
||||
<target name="-post-clean">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
|
||||
<target name="-check-call-dep">
|
||||
<property file="${call.built.properties}" prefix="already.built."/>
|
||||
<condition property="should.call.dep">
|
||||
<not>
|
||||
<isset property="already.built.${call.subproject}"/>
|
||||
</not>
|
||||
</condition>
|
||||
</target>
|
||||
<target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
|
||||
<ant antfile="${call.script}" inheritall="false" target="${call.target}">
|
||||
<propertyset>
|
||||
<propertyref prefix="transfer."/>
|
||||
<mapper from="transfer.*" to="*" type="glob"/>
|
||||
</propertyset>
|
||||
</ant>
|
||||
</target>
|
||||
</project>
|
||||
8
ws2012/P2P/uebungen/11/nbproject/genfiles.properties
Normal file
8
ws2012/P2P/uebungen/11/nbproject/genfiles.properties
Normal file
@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=b48d6d8f
|
||||
build.xml.script.CRC32=d537a005
|
||||
build.xml.stylesheet.CRC32=28e38971@1.38.3.45
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=b48d6d8f
|
||||
nbproject/build-impl.xml.script.CRC32=0fa0a410
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=229523de@1.38.3.45
|
||||
@ -0,0 +1,6 @@
|
||||
compile.on.save=true
|
||||
do.depend=false
|
||||
do.jar=true
|
||||
javac.debug=true
|
||||
javadoc.preview=true
|
||||
user.properties.file=C:\\Users\\rylon\\.netbeans\\6.9\\build.properties
|
||||
81
ws2012/P2P/uebungen/11/nbproject/project.properties
Normal file
81
ws2012/P2P/uebungen/11/nbproject/project.properties
Normal file
@ -0,0 +1,81 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
application.title=p2p_u5
|
||||
application.vendor=rylon
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/p2p_u5.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
endorsed.classpath=
|
||||
excludes=
|
||||
file.reference.11-src=src
|
||||
includes=**
|
||||
jar.archive.disabled=${jnlp.enabled}
|
||||
jar.compress=false
|
||||
jar.index=${jnlp.enabled}
|
||||
javac.classpath=
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.7
|
||||
javac.target=1.7
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}:\
|
||||
${libs.junit.classpath}:\
|
||||
${libs.junit_4.classpath}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
jnlp.codebase.type=no.codebase
|
||||
jnlp.descriptor=application
|
||||
jnlp.enabled=false
|
||||
jnlp.mixed.code=defaut
|
||||
jnlp.offline-allowed=false
|
||||
jnlp.signed=false
|
||||
main.class=CLI
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
platform.active=JDK_1.7
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project
|
||||
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
|
||||
# or test-sys-prop.name=value to set system properties for unit tests):
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=${file.reference.11-src}
|
||||
14
ws2012/P2P/uebungen/11/nbproject/project.xml
Normal file
14
ws2012/P2P/uebungen/11/nbproject/project.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>p2p_u5</name>
|
||||
<explicit-platform explicit-source-supported="true"/>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots/>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
54
ws2012/P2P/uebungen/11/src/CLI.java
Normal file
54
ws2012/P2P/uebungen/11/src/CLI.java
Normal file
@ -0,0 +1,54 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.logging.LogManager;
|
||||
|
||||
import node.Node;
|
||||
import node.NodeIdentifier;
|
||||
|
||||
public class CLI {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
System.setProperty("java.util.logging.config.file",
|
||||
"logging.properties");
|
||||
|
||||
try {
|
||||
LogManager.getLogManager().readConfiguration();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Node node = new Node();
|
||||
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
|
||||
String s;
|
||||
while ((s = in.readLine()) != null && s.length() != 0) {
|
||||
String[] splitted = s.split(" ");
|
||||
|
||||
String cmd = splitted[0];
|
||||
|
||||
switch (cmd) {
|
||||
case "status":
|
||||
for (NodeIdentifier id : node.getNeighbors()) {
|
||||
System.out.println(id);
|
||||
}
|
||||
break;
|
||||
case "lookup":
|
||||
// TODO not implemented
|
||||
if (splitted.length < 2) {
|
||||
System.out.println("Too few arguments.");
|
||||
} else {
|
||||
String key = splitted[1];
|
||||
}
|
||||
System.out.println("not implemented");
|
||||
break;
|
||||
case "leave":
|
||||
node.leave();
|
||||
break;
|
||||
default:
|
||||
System.out.println("Unknown command.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
140
ws2012/P2P/uebungen/11/src/message/Ack.java
Normal file
140
ws2012/P2P/uebungen/11/src/message/Ack.java
Normal file
@ -0,0 +1,140 @@
|
||||
package message;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import node.Identifier;
|
||||
import node.NodeIdentifier;
|
||||
import util.BufferUtil;
|
||||
|
||||
public class Ack {
|
||||
private final static Logger LOGGER = Logger.getLogger(Ack.class.getName());
|
||||
|
||||
/**
|
||||
* timeout in seconds
|
||||
*/
|
||||
private static final int TIMEOUT = 1000;
|
||||
|
||||
/**
|
||||
* Maximum number of retries
|
||||
*/
|
||||
private static final int MAX_RETRIES = 3;
|
||||
|
||||
private Identifier rpcId;
|
||||
|
||||
private NodeIdentifier receiver;
|
||||
|
||||
private ByteBuffer buffer;
|
||||
|
||||
private int numRetries = 0;
|
||||
|
||||
private TimeoutThread timeout;
|
||||
private Thread thread;
|
||||
|
||||
// The channel to re-send the message on
|
||||
private DatagramChannel channel;
|
||||
|
||||
private MessageCallback callback;
|
||||
|
||||
public Ack(Identifier id, NodeIdentifier receiver, DatagramChannel channel,
|
||||
ByteBuffer buffer, MessageCallback cb) {
|
||||
this.rpcId = id;
|
||||
this.receiver = receiver;
|
||||
this.channel = channel;
|
||||
this.buffer = BufferUtil.clone(buffer);
|
||||
this.callback = cb;
|
||||
startThread();
|
||||
}
|
||||
|
||||
private void startThread() {
|
||||
LOGGER.log(Level.FINEST, "Starting timeout thread for RPC " + rpcId);
|
||||
timeout = new TimeoutThread();
|
||||
thread = new Thread(timeout);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public Identifier getID() {
|
||||
return rpcId;
|
||||
}
|
||||
|
||||
public boolean check(NodeIdentifier fromID) {
|
||||
return fromID.equals(receiver);
|
||||
}
|
||||
|
||||
public ByteBuffer getBuf() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public void setBuf(ByteBuffer buf) {
|
||||
this.buffer = buf;
|
||||
}
|
||||
|
||||
public void setReceived() {
|
||||
// Stop thread
|
||||
try {
|
||||
if (thread != null) {
|
||||
timeout.terminate();
|
||||
thread.join();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
private class TimeoutThread implements Runnable {
|
||||
private volatile boolean notReceived = true;
|
||||
|
||||
// When do we stop expecting the ack
|
||||
private long timeToStop = System.currentTimeMillis() + TIMEOUT;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (notReceived && System.currentTimeMillis() < timeToStop) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Timeout hit!
|
||||
|
||||
if (notReceived) {
|
||||
|
||||
if (numRetries < MAX_RETRIES) {
|
||||
try {
|
||||
LOGGER.log(
|
||||
Level.FINE,
|
||||
"Didn't receive RPC Ack {0} by now. Resending... ",
|
||||
new Object[] { rpcId });
|
||||
channel.send(buffer, receiver.getAddress());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
startThread();
|
||||
numRetries++;
|
||||
} else {
|
||||
|
||||
LOGGER.log(Level.INFO, "Absent RPC ack {0}.",
|
||||
new Object[] { rpcId });
|
||||
|
||||
if (callback != null) {
|
||||
callback.onTimeout();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Message has been received in time
|
||||
if (callback != null) {
|
||||
callback.onReceive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
notReceived = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
22
ws2012/P2P/uebungen/11/src/message/MessageCallback.java
Normal file
22
ws2012/P2P/uebungen/11/src/message/MessageCallback.java
Normal file
@ -0,0 +1,22 @@
|
||||
package message;
|
||||
|
||||
/**
|
||||
* A callback to create asynchronous events that get triggered when a message
|
||||
* (ack/answer) is received.
|
||||
*
|
||||
* @author jln
|
||||
*
|
||||
*/
|
||||
public interface MessageCallback {
|
||||
|
||||
/**
|
||||
* Called when the awaited message arrives.
|
||||
*/
|
||||
public void onReceive();
|
||||
|
||||
/**
|
||||
* Called when the awaited message doesn't arrive (even after possible
|
||||
* retries).
|
||||
*/
|
||||
public void onTimeout();
|
||||
}
|
||||
15
ws2012/P2P/uebungen/11/src/message/MessageType.java
Normal file
15
ws2012/P2P/uebungen/11/src/message/MessageType.java
Normal file
@ -0,0 +1,15 @@
|
||||
package message;
|
||||
|
||||
public class MessageType {
|
||||
public final static byte FIND_NODE = 0;
|
||||
public final static byte NODES = 1;
|
||||
|
||||
public final static byte PING = 10;
|
||||
public final static byte PONG = 11;
|
||||
|
||||
public final static byte LEAVE = 2;
|
||||
|
||||
public final static byte FIND_VALUE = 4;
|
||||
public final static byte STORE = 5;
|
||||
public final static byte DATA = 6;
|
||||
}
|
||||
111
ws2012/P2P/uebungen/11/src/node/Identifier.java
Normal file
111
ws2012/P2P/uebungen/11/src/node/Identifier.java
Normal file
@ -0,0 +1,111 @@
|
||||
package node;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.BitSet;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* A Kademlia identifier. Can be used for identifying files as well as nodes
|
||||
* (but for nodes check {@see NodeIdentifier}).
|
||||
*
|
||||
* @author jln
|
||||
*
|
||||
*/
|
||||
public class Identifier {
|
||||
private static Random random = new Random(System.currentTimeMillis());
|
||||
|
||||
protected BitSet bits;
|
||||
|
||||
private int size;
|
||||
|
||||
public Identifier(int size, byte[] bytes) {
|
||||
this.size = size;
|
||||
this.bits = BitSet.valueOf(bytes);
|
||||
}
|
||||
|
||||
private Identifier(int size, BitSet bits) {
|
||||
this.size = size;
|
||||
this.bits = bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ID exactly "in the middle" of the ID space. (If the ID space
|
||||
* is 8 bit wide, this returns an ID valued 128).
|
||||
*
|
||||
* @param size
|
||||
* the size of the id space
|
||||
* @return an Identifier
|
||||
*/
|
||||
public static Identifier getStaticIdentifier(int size) {
|
||||
BitSet middle = new BitSet(size);
|
||||
middle.set(size - 1);
|
||||
return new Identifier(size, middle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a random ID for the given id space size.
|
||||
*
|
||||
* @param size
|
||||
* the size of the id space
|
||||
* @return a random Identifier
|
||||
*/
|
||||
public static Identifier getRandomIdentifier(int size) {
|
||||
BitSet bits = new BitSet(size);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
double threshold = random.nextGaussian();
|
||||
if (threshold > 0) {
|
||||
bits.set(i);
|
||||
}
|
||||
}
|
||||
|
||||
return new Identifier(size, bits);
|
||||
}
|
||||
|
||||
public BigInteger distanceTo(Identifier otherID) {
|
||||
BitSet distance = (BitSet) bits.clone();
|
||||
distance.xor(otherID.bits);
|
||||
return new BigInteger(1, distance.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the bit at the given position is set or not. The MSB is
|
||||
* at position 0.
|
||||
*
|
||||
* @param index
|
||||
* the index to check
|
||||
* @return true if the bit is set
|
||||
*/
|
||||
public boolean isBitSetAt(int index) {
|
||||
BigInteger intValue = new BigInteger(1, bits.toByteArray());
|
||||
int numOfTrimmedZeros = size - intValue.bitLength();
|
||||
|
||||
if (index < numOfTrimmedZeros) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return bits.get(bits.length() - (index + numOfTrimmedZeros) - 1);
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return bits.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Identifier)) {
|
||||
return false;
|
||||
} else {
|
||||
return bits.equals(((Identifier) o).bits);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new BigInteger(1, bits.toByteArray()).toString();
|
||||
}
|
||||
}
|
||||
341
ws2012/P2P/uebungen/11/src/node/Node.java
Normal file
341
ws2012/P2P/uebungen/11/src/node/Node.java
Normal file
@ -0,0 +1,341 @@
|
||||
package node;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import message.Ack;
|
||||
import message.MessageCallback;
|
||||
import message.MessageType;
|
||||
import routingtable.IRoutingTable;
|
||||
import routingtable.RoutingTableImpl;
|
||||
|
||||
public class Node {
|
||||
private final static Logger LOGGER = Logger.getLogger(Node.class.getName());
|
||||
|
||||
/**
|
||||
* Size of ID space (has to be a multiple of 8)
|
||||
*/
|
||||
public static final int ID_BITS = 8;
|
||||
/**
|
||||
* The bucket size
|
||||
*/
|
||||
public static final int BUCKET_SIZE = 2;
|
||||
/**
|
||||
* The first node is always spawned on port 50000
|
||||
*/
|
||||
private static final int INITIAL_PORT = 50000;
|
||||
private static final Identifier INITIAL_ID = Identifier.getStaticIdentifier(ID_BITS);
|
||||
private static final int BUFFER_SIZE = 512;
|
||||
/**
|
||||
* The size of an IP address (in bytes)
|
||||
*/
|
||||
public static final int SIZE_IP_ADDRESS = 8;
|
||||
|
||||
private InetSocketAddress address;
|
||||
private DatagramChannel channel;
|
||||
|
||||
private Map<Identifier, List<Ack>> rpcs = new HashMap<Identifier, List<Ack>>();
|
||||
|
||||
private Thread thread;
|
||||
private UDPHandler udpListen;
|
||||
|
||||
private Identifier nodeID = Identifier.getRandomIdentifier(ID_BITS);
|
||||
private IRoutingTable routingTable = new RoutingTableImpl(BUCKET_SIZE, this);
|
||||
|
||||
public Node() {
|
||||
System.setProperty("java.net.preferIPv4Stack", "true");
|
||||
|
||||
try {
|
||||
channel = DatagramChannel.open();
|
||||
|
||||
try {
|
||||
address = new InetSocketAddress("localhost", INITIAL_PORT);
|
||||
channel.socket().bind(address);
|
||||
|
||||
this.nodeID = INITIAL_ID;
|
||||
} catch (SocketException e) {
|
||||
// The initial port is already bound -> let the system pick a
|
||||
// port
|
||||
channel.socket().bind(new InetSocketAddress("localhost", 0));
|
||||
address = (InetSocketAddress) channel.getLocalAddress();
|
||||
}
|
||||
|
||||
channel.configureBlocking(false);
|
||||
|
||||
udpListen = new UDPHandler(this);
|
||||
thread = new Thread(udpListen);
|
||||
thread.start();
|
||||
|
||||
LOGGER.log(Level.INFO, "{0}: Initialized node {1} on {2}", new Object[] { this.nodeID, getName(), address.toString() });
|
||||
|
||||
if (address.getPort() != INITIAL_PORT) {
|
||||
// The port of this node is not the "INITIAL_PORT" (so it's not
|
||||
// the first node in the network). So we try to join the network
|
||||
// via the first node.
|
||||
NodeIdentifier viaNode = new NodeIdentifier(ID_BITS,
|
||||
INITIAL_ID.getBytes(), new InetSocketAddress(
|
||||
"127.0.0.1", INITIAL_PORT));
|
||||
joinNetworkVia(viaNode);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void joinNetworkVia(NodeIdentifier viaNode) {
|
||||
LOGGER.log(Level.INFO, "Trying to join network via node {0}",
|
||||
new Object[] { viaNode });
|
||||
|
||||
routingTable.insert(viaNode);
|
||||
sendFindNode(viaNode, this.nodeID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns new ID (usually used as a RPC ID). This makes sure
|
||||
* the ID is not yet used (in this node).
|
||||
*
|
||||
* @return an ID
|
||||
*/
|
||||
private Identifier createRPCID() {
|
||||
Identifier rpcID = Identifier.getRandomIdentifier(ID_BITS);
|
||||
while (rpcs.containsKey(rpcID)) {
|
||||
rpcID = Identifier.getRandomIdentifier(ID_BITS);
|
||||
}
|
||||
return rpcID;
|
||||
}
|
||||
|
||||
void sendFindNode(NodeIdentifier receiver, Identifier idToFind) {
|
||||
boolean successful = send(receiver, MessageType.FIND_NODE,
|
||||
idToFind.getBytes(), true, null);
|
||||
|
||||
if (successful) {
|
||||
LOGGER.log(Level.INFO, "Sending [FIND_NODE {0}] to node {1}",
|
||||
new Object[] { idToFind, receiver });
|
||||
}
|
||||
}
|
||||
|
||||
void sendFindValue(NodeIdentifier receiver, Identifier idToFind) {
|
||||
boolean successful = send(receiver, MessageType.FIND_VALUE,
|
||||
idToFind.getBytes(), true, null);
|
||||
|
||||
if (successful) {
|
||||
LOGGER.log(Level.INFO, "Sending [FIND_VALUE {0}] to node {1}",
|
||||
new Object[] { idToFind, receiver });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all nodes of this nodes routing table, that a close to a given node
|
||||
* and sends that list to a specific node.
|
||||
*
|
||||
* @param receiver
|
||||
* The node to receive the list of nodes
|
||||
* @param idToFind
|
||||
* The ID to find close nodes of
|
||||
* @param rpcID
|
||||
* An RPC ID (because this is always an answer to a FIND_NODE
|
||||
* RPC)
|
||||
*/
|
||||
void sendClosestNodesTo(NodeIdentifier receiver, Identifier idToFind, Identifier rpcID) {
|
||||
//TODO modify to match FIND_VALUE
|
||||
Set<NodeIdentifier> closeNodes = routingTable.getClosestNodesTo(idToFind);
|
||||
int numNodes = closeNodes.size();
|
||||
|
||||
ByteBuffer nodes = ByteBuffer.allocate(numNodes * (ID_BITS / 8)
|
||||
+ numNodes * SIZE_IP_ADDRESS);
|
||||
|
||||
for (NodeIdentifier idToSend : closeNodes) {
|
||||
// Don't send the node to itself
|
||||
if (!receiver.equals(idToSend)) {
|
||||
nodes.put(idToSend.getTripleAsBytes());
|
||||
}
|
||||
}
|
||||
|
||||
boolean successful = send(receiver, MessageType.NODES, rpcID,
|
||||
nodes.array(), false, null);
|
||||
|
||||
if (successful) {
|
||||
LOGGER.log(
|
||||
Level.INFO,
|
||||
"Sending {0} nodes to to node {1} [FIND_NODE {2}] (rpcID={3})",
|
||||
new Object[] { closeNodes.size(), receiver, idToFind, rpcID });
|
||||
}
|
||||
}
|
||||
|
||||
public void sendPing(NodeIdentifier receiver, MessageCallback cb) {
|
||||
boolean successful = send(receiver, MessageType.PING, null, true, cb);
|
||||
|
||||
if (successful) {
|
||||
LOGGER.log(Level.INFO, "Sending [PING] to node {0}",
|
||||
new Object[] { receiver });
|
||||
}
|
||||
}
|
||||
|
||||
void sendPong(NodeIdentifier receiver, Identifier rpcID) {
|
||||
boolean successful = send(receiver, MessageType.PONG, rpcID, null,
|
||||
false, null);
|
||||
|
||||
if (successful) {
|
||||
LOGGER.log(Level.INFO, "Sending [PONG] to {0} (rpcID={1})",
|
||||
new Object[] { receiver, rpcID });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a given ID (with a given RPC ID). You usually want to
|
||||
* use this method when you know the RPC ID beforehand (e.g. if this is an
|
||||
* ack or answer to a prior message).
|
||||
*
|
||||
* @param to
|
||||
* the ID to send to
|
||||
* @param messageType
|
||||
* the message type
|
||||
* @param data
|
||||
* the data to send
|
||||
* @param reliable
|
||||
* flag, whether this has to be acked or not
|
||||
* @param cb
|
||||
* A callback that is executed when this message gets acked (or
|
||||
* answered). This obviously is only of interest when the
|
||||
* reliable flag is true
|
||||
* @return true if the message was sent successfully
|
||||
*/
|
||||
private boolean send(NodeIdentifier to, byte messageType, byte[] data,
|
||||
boolean reliable, MessageCallback cb) {
|
||||
return send(to, messageType, createRPCID(), data, reliable, cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a given ID (with a given RPC ID). You usually want to
|
||||
* use this method when you know the RPC ID beforehand (e.g. if this is an
|
||||
* ack or answer to a prior message).
|
||||
*
|
||||
* @param to
|
||||
* the ID to send to
|
||||
* @param messageType
|
||||
* the message type
|
||||
* @param rpcID
|
||||
* the RPC ID of this message (if you don't know this use
|
||||
* {@link #send(NodeIdentifier, byte, byte[], boolean, MessageCallback)}
|
||||
* and a new random ID will be created)
|
||||
* @param data
|
||||
* the data to send
|
||||
* @param reliable
|
||||
* flag, whether this has to be acked or not
|
||||
* @param cb
|
||||
* A callback that is executed when this message gets acked (or
|
||||
* answered). This obviously is only of interest when the
|
||||
* reliable flag is true
|
||||
* @return true if the message was sent successfully
|
||||
*/
|
||||
private boolean send(NodeIdentifier to, byte messageType, Identifier rpcID,
|
||||
byte[] data, boolean reliable, MessageCallback cb) {
|
||||
|
||||
boolean successful = true;
|
||||
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
|
||||
|
||||
buffer.put(messageType);
|
||||
buffer.put(this.nodeID.getBytes());
|
||||
buffer.put(rpcID.getBytes());
|
||||
|
||||
if (data != null) {
|
||||
buffer.put(data);
|
||||
}
|
||||
|
||||
buffer.flip();
|
||||
|
||||
try {
|
||||
|
||||
channel.send(buffer, to.getAddress());
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
LOGGER.log(Level.SEVERE, "Failed to write to channel", e);
|
||||
successful = false;
|
||||
|
||||
} finally {
|
||||
// Even if an exception occurred this should be reliable
|
||||
if (reliable) {
|
||||
|
||||
Ack newAck = new Ack(rpcID, to, channel, buffer, cb);
|
||||
if (rpcs.containsKey(rpcID)) {
|
||||
rpcs.get(rpcID).add(newAck);
|
||||
} else {
|
||||
rpcs.put(rpcID, new ArrayList<Ack>());
|
||||
rpcs.get(rpcID).add(newAck);
|
||||
}
|
||||
}
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return nodeID.toString();
|
||||
}
|
||||
|
||||
public boolean hasAcks() {
|
||||
return !rpcs.isEmpty();
|
||||
}
|
||||
|
||||
public DatagramChannel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public void updateBuckets(NodeIdentifier id) {
|
||||
routingTable.insert(id);
|
||||
}
|
||||
|
||||
public Identifier getID() {
|
||||
return nodeID;
|
||||
}
|
||||
|
||||
public Set<NodeIdentifier> getNeighbors() {
|
||||
return routingTable.getEntries();
|
||||
}
|
||||
|
||||
public boolean receivedRPC(NodeIdentifier fromID, Identifier rpcID) {
|
||||
List<Ack> rpcsFromID = rpcs.get(rpcID);
|
||||
boolean removedAck = false;
|
||||
|
||||
for (Ack ack : rpcsFromID) {
|
||||
if (ack.check(fromID)) {
|
||||
ack.setReceived();
|
||||
rpcsFromID.remove(ack);
|
||||
removedAck = true;
|
||||
|
||||
LOGGER.log(Level.FINEST, "Received RPC ack " + rpcID);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!removedAck) {
|
||||
LOGGER.log(Level.WARNING,
|
||||
"Received RPC ack {0}, but didn't expect that",
|
||||
new Object[] { rpcID });
|
||||
}
|
||||
|
||||
return removedAck;
|
||||
}
|
||||
|
||||
public void leave() {
|
||||
for (NodeIdentifier n : getNeighbors()) {
|
||||
sendLeave(n);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private boolean sendLeave(NodeIdentifier n) {
|
||||
return send(n, MessageType.LEAVE, null, false, null);
|
||||
}
|
||||
}
|
||||
35
ws2012/P2P/uebungen/11/src/node/NodeIdentifier.java
Normal file
35
ws2012/P2P/uebungen/11/src/node/NodeIdentifier.java
Normal file
@ -0,0 +1,35 @@
|
||||
package node;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import util.BufferUtil;
|
||||
|
||||
/**
|
||||
* Same as a {@link Identifier}, but this also stores an IP address.
|
||||
*
|
||||
* @author jln
|
||||
*
|
||||
*/
|
||||
public class NodeIdentifier extends Identifier {
|
||||
|
||||
private InetSocketAddress address;
|
||||
|
||||
public NodeIdentifier(int size, byte[] bytes, InetSocketAddress address) {
|
||||
super(size, bytes);
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public byte[] getTripleAsBytes() {
|
||||
ByteBuffer result = ByteBuffer.allocate(Node.SIZE_IP_ADDRESS
|
||||
+ (Node.ID_BITS / 8));
|
||||
|
||||
result.put(BufferUtil.addrToBytes(address));
|
||||
result.put(bits.toByteArray());
|
||||
return result.array();
|
||||
}
|
||||
|
||||
public InetSocketAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
}
|
||||
220
ws2012/P2P/uebungen/11/src/node/UDPHandler.java
Normal file
220
ws2012/P2P/uebungen/11/src/node/UDPHandler.java
Normal file
@ -0,0 +1,220 @@
|
||||
package node;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import message.MessageType;
|
||||
|
||||
public class UDPHandler implements Runnable {
|
||||
private final static Logger LOGGER = Logger.getLogger(UDPHandler.class.getName());
|
||||
|
||||
public static final int BUF_SIZE = 512;
|
||||
|
||||
private volatile boolean running = true;
|
||||
private ByteBuffer buffer = ByteBuffer.allocate(BUF_SIZE);
|
||||
|
||||
private Node node;
|
||||
|
||||
public UDPHandler(Node node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the buffer of this UDPHandler as is and tries to read an IP address
|
||||
* (4 bytes and 1 int) from it. If there is no/incomplete or wrong data,
|
||||
* this will fail.
|
||||
*
|
||||
* @return the address that has been read
|
||||
*/
|
||||
private InetSocketAddress getIPFromBuffer() {
|
||||
StringBuilder theAddr = new StringBuilder();
|
||||
// Read 4 Bytes and 1 Integer = 1 IP address
|
||||
for (int i = 0; i < 4; i++) {
|
||||
theAddr.append(buffer.get());
|
||||
if (i < 3) {
|
||||
theAddr.append(".");
|
||||
}
|
||||
}
|
||||
int port = buffer.getInt();
|
||||
return new InetSocketAddress(theAddr.toString(), port);
|
||||
}
|
||||
|
||||
private Identifier getIDFromBuffer() {
|
||||
int numBytes = Node.ID_BITS / 8;
|
||||
byte[] result = new byte[numBytes];
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
result[i] = buffer.get();
|
||||
}
|
||||
return new Identifier(Node.ID_BITS, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a triple <IP address, port, id> from the channel and returns a
|
||||
* {@link node.NodeIdentifier}.
|
||||
*
|
||||
* @return the read node ID
|
||||
*/
|
||||
private NodeIdentifier getNodeTripleFromBuffer() {
|
||||
InetSocketAddress address = getIPFromBuffer();
|
||||
|
||||
int numBytes = Node.ID_BITS / 8;
|
||||
byte[] result = new byte[numBytes];
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
result[i] = buffer.get();
|
||||
}
|
||||
return new NodeIdentifier(Node.ID_BITS, result, address);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
InetSocketAddress from = null;
|
||||
|
||||
// Run until it gets killed, and all my Acks have been answered
|
||||
while (running || node.hasAcks()) {
|
||||
try {
|
||||
// Flag that indicates whether the routing table should be
|
||||
// updated with the node we just received a message from. This
|
||||
// needs to be done, because some messages trigger a direct
|
||||
// answer. For example we send a PING to a node. That node
|
||||
// answers with a PONG. Because we received a message from that
|
||||
// node we will update our routing table and see that we already
|
||||
// know this node. So we will PING that node...
|
||||
boolean updateRT = true;
|
||||
|
||||
// The address of the node that sent this message
|
||||
from = (InetSocketAddress) node.getChannel().receive(buffer);
|
||||
|
||||
// channel.receive() is non-blocking. So we need to check if
|
||||
// something actually has been written to the buffer
|
||||
if (buffer.remaining() != BUF_SIZE) {
|
||||
buffer.flip();
|
||||
|
||||
byte messageType = buffer.get();
|
||||
|
||||
NodeIdentifier fromID = new NodeIdentifier(Node.ID_BITS,
|
||||
getIDFromBuffer().getBytes(), from);
|
||||
|
||||
Identifier rpcID = getIDFromBuffer();
|
||||
|
||||
switch (messageType) {
|
||||
case MessageType.FIND_NODE:
|
||||
receiveFindNode(fromID, rpcID);
|
||||
break;
|
||||
case MessageType.NODES:
|
||||
receiveNodes(fromID, rpcID);
|
||||
break;
|
||||
case MessageType.PING:
|
||||
updateRT = false;
|
||||
receivePing(fromID, rpcID);
|
||||
break;
|
||||
case MessageType.PONG:
|
||||
updateRT = false;
|
||||
receivePong(fromID, rpcID);
|
||||
break;
|
||||
case MessageType.LEAVE:
|
||||
// We don't have to do anything here because, after this
|
||||
// switch block we call node.updateBuckets(...) which
|
||||
// will try to ping the node we received this leave
|
||||
// message from. That node will not answered because it
|
||||
// directly shut down after sending the leave message.
|
||||
// So the node will be removed from this routing table.
|
||||
LOGGER.log(Level.INFO, "Received leave from {0}",
|
||||
new Object[] { from.toString() });
|
||||
break;
|
||||
case MessageType.FIND_VALUE:
|
||||
//TODO implement
|
||||
LOGGER.log(Level.INFO, "Received FIND_VALUE from {0}",
|
||||
new Object[] { from.toString() });
|
||||
break;
|
||||
case MessageType.STORE:
|
||||
//TODO implemnt
|
||||
LOGGER.log(Level.INFO, "Received STORE from {0}",
|
||||
new Object[] { from.toString() });
|
||||
break;
|
||||
case MessageType.DATA:
|
||||
//TODO implemnt
|
||||
LOGGER.log(Level.INFO, "Received DATA from {0}",
|
||||
new Object[] { from.toString() });
|
||||
break;
|
||||
default:
|
||||
LOGGER.log(Level.INFO,
|
||||
"Received unknown command from {0}: [{1}]{2}",
|
||||
new Object[] { from.toString(), messageType,
|
||||
new String(buffer.array()) });
|
||||
}
|
||||
|
||||
if (updateRT) {
|
||||
node.updateBuckets(new NodeIdentifier(Node.ID_BITS,
|
||||
fromID.getBytes(), from));
|
||||
}
|
||||
|
||||
} else {
|
||||
// If nothing has been read/received wait and read/receive
|
||||
// again
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
buffer.clear();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void receivePong(NodeIdentifier fromID, Identifier rpcID) {
|
||||
LOGGER.log(Level.INFO, "Received [PONG] from {0}",
|
||||
new Object[] { fromID });
|
||||
|
||||
// This should be the answer to a prior PING -> mark this RPC ID as
|
||||
// received
|
||||
node.receivedRPC(fromID, rpcID);
|
||||
}
|
||||
|
||||
private void receivePing(NodeIdentifier fromID, Identifier rpcID) {
|
||||
LOGGER.log(Level.INFO, "Received [PING] from {0}",
|
||||
new Object[] { fromID });
|
||||
node.sendPong(fromID, rpcID);
|
||||
}
|
||||
|
||||
private void receiveNodes(NodeIdentifier fromID, Identifier rpcID) {
|
||||
|
||||
int numReceived = 0;
|
||||
|
||||
// This is just for the log message
|
||||
StringBuilder nodes = new StringBuilder();
|
||||
|
||||
while (buffer.hasRemaining()) {
|
||||
NodeIdentifier newID = getNodeTripleFromBuffer();
|
||||
node.updateBuckets(newID);
|
||||
nodes.append(newID).append(", ");
|
||||
numReceived++;
|
||||
}
|
||||
|
||||
// This should be the answer to a prior FIND_NODE -> mark this RPC ID as
|
||||
// received
|
||||
node.receivedRPC(fromID, rpcID);
|
||||
|
||||
LOGGER.log(Level.INFO, "Received {0} [NODES] [{1}] from Node {2})",
|
||||
new Object[] { numReceived, nodes.toString(), fromID });
|
||||
}
|
||||
|
||||
private void receiveFindNode(NodeIdentifier fromID, Identifier rpc_id) {
|
||||
Identifier idToFind = getIDFromBuffer();
|
||||
|
||||
LOGGER.log(Level.INFO, "Received [FIND_NODE {0}] from Node {1}",
|
||||
new Object[] { idToFind, fromID });
|
||||
|
||||
node.sendClosestNodesTo(fromID, idToFind, rpc_id);
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
145
ws2012/P2P/uebungen/11/src/routingtable/Bucket.java
Normal file
145
ws2012/P2P/uebungen/11/src/routingtable/Bucket.java
Normal file
@ -0,0 +1,145 @@
|
||||
package routingtable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import message.MessageCallback;
|
||||
import node.Node;
|
||||
import node.NodeIdentifier;
|
||||
|
||||
public class Bucket {
|
||||
private final static Logger LOGGER = Logger.getLogger(Bucket.class
|
||||
.getName());
|
||||
|
||||
private Bucket left;
|
||||
private Bucket right;
|
||||
|
||||
private List<NodeIdentifier> entries;
|
||||
|
||||
private int bucketSize;
|
||||
private int level;
|
||||
|
||||
private Node node;
|
||||
|
||||
public Bucket(int bucketSize, int level, Node node) {
|
||||
this.bucketSize = bucketSize;
|
||||
this.level = level;
|
||||
this.node = node;
|
||||
entries = new ArrayList<NodeIdentifier>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nodes of this very bucket.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<NodeIdentifier> getNodes() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
public boolean contains(NodeIdentifier id) {
|
||||
if (!isLeaf()) {
|
||||
return left.contains(id) || right.contains(id);
|
||||
}
|
||||
return entries.contains(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to update the given node.
|
||||
*
|
||||
* @param id
|
||||
* @return true if the node is still available, else false
|
||||
*/
|
||||
public void update(final NodeIdentifier id) {
|
||||
if (!isLeaf()) {
|
||||
if (id.isBitSetAt(level)) {
|
||||
left.update(id);
|
||||
} else {
|
||||
right.update(id);
|
||||
}
|
||||
} else {
|
||||
node.sendPing(id, new MessageCallback() {
|
||||
@Override
|
||||
public void onReceive() {
|
||||
LOGGER.log(Level.INFO,
|
||||
"Node answered in time, moving to top of list.");
|
||||
entries.remove(id);
|
||||
entries.add(0, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
LOGGER.log(Level.INFO, "Node didnt answer in time.");
|
||||
// TODO: this should be propagated to the "upper" Routing
|
||||
// Table, not just to this specific bucket
|
||||
entries.remove(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void insert(NodeIdentifier newId) {
|
||||
insert(newId, "");
|
||||
}
|
||||
|
||||
public void insert(NodeIdentifier newId, String path) {
|
||||
if (isLeaf()) {
|
||||
if (entries.size() < bucketSize) {
|
||||
LOGGER.log(Level.INFO,
|
||||
"Added node {0} to RT [{1}] on level {2}",
|
||||
new Object[] { newId, path, level });
|
||||
entries.add(newId);
|
||||
} else {
|
||||
LOGGER.log(Level.INFO, "Split on level " + level
|
||||
+ " while adding " + newId);
|
||||
|
||||
LOGGER.log(Level.INFO,
|
||||
"Distributing present nodes to lower buckets");
|
||||
|
||||
Bucket newLeft = new Bucket(bucketSize, level + 1, node);
|
||||
Bucket newRight = new Bucket(bucketSize, level + 1, node);
|
||||
|
||||
// Add the new entry and in the following loop distribute all
|
||||
// existing entries to left/right
|
||||
entries.add(newId);
|
||||
|
||||
for (NodeIdentifier id : entries) {
|
||||
if (id.isBitSetAt(level)) {
|
||||
newLeft.insert(id, path + "1");
|
||||
} else {
|
||||
newRight.insert(id, path + "0");
|
||||
}
|
||||
}
|
||||
|
||||
this.entries = null;
|
||||
this.left = newLeft;
|
||||
this.right = newRight;
|
||||
}
|
||||
} else {
|
||||
if (newId.isBitSetAt(level)) {
|
||||
left.insert(newId, path + "1");
|
||||
} else {
|
||||
right.insert(newId, path + "0");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isLeaf() {
|
||||
return left == null && right == null;
|
||||
}
|
||||
|
||||
public void remove(NodeIdentifier node) {
|
||||
if (isLeaf()) {
|
||||
entries.remove(node);
|
||||
} else {
|
||||
if (node.isBitSetAt(level)) {
|
||||
left.remove(node);
|
||||
} else {
|
||||
right.remove(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
ws2012/P2P/uebungen/11/src/routingtable/IRoutingTable.java
Normal file
19
ws2012/P2P/uebungen/11/src/routingtable/IRoutingTable.java
Normal file
@ -0,0 +1,19 @@
|
||||
package routingtable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import node.Identifier;
|
||||
import node.NodeIdentifier;
|
||||
|
||||
public interface IRoutingTable {
|
||||
|
||||
public void insert(NodeIdentifier id);
|
||||
|
||||
public Set<NodeIdentifier> getClosestNodesTo(Identifier id);
|
||||
|
||||
public boolean contains(NodeIdentifier node);
|
||||
|
||||
public void remove(NodeIdentifier node);
|
||||
|
||||
public Set<NodeIdentifier> getEntries();
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
package routingtable;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import node.Identifier;
|
||||
import node.Node;
|
||||
import node.NodeIdentifier;
|
||||
|
||||
public class RoutingTableImpl implements IRoutingTable {
|
||||
private Set<NodeIdentifier> entries = new HashSet<NodeIdentifier>();
|
||||
|
||||
private Bucket root;
|
||||
|
||||
private int bucketSize;
|
||||
|
||||
public RoutingTableImpl(int bucketSize, Node node) {
|
||||
this.bucketSize = bucketSize;
|
||||
this.root = new Bucket(bucketSize, 0, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(NodeIdentifier id) {
|
||||
if (root.contains(id)) {
|
||||
root.update(id);
|
||||
} else {
|
||||
entries.add(id);
|
||||
root.insert(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<NodeIdentifier> getClosestNodesTo(final Identifier id) {
|
||||
Set<NodeIdentifier> result = new HashSet<NodeIdentifier>();
|
||||
|
||||
if (entries.size() <= bucketSize) {
|
||||
result.addAll(entries);
|
||||
|
||||
} else {
|
||||
List<NodeIdentifier> temp = new ArrayList<NodeIdentifier>(entries);
|
||||
|
||||
Collections.sort(temp, new Comparator<NodeIdentifier>() {
|
||||
@Override
|
||||
public int compare(NodeIdentifier o1, NodeIdentifier o2) {
|
||||
BigInteger dist1 = id.distanceTo(o1);
|
||||
BigInteger dist2 = id.distanceTo(o2);
|
||||
return dist1.compareTo(dist2);
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < bucketSize; i++) {
|
||||
result.add(temp.get(i));
|
||||
}
|
||||
result = new HashSet<NodeIdentifier>(temp.subList(0,
|
||||
Node.BUCKET_SIZE));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(NodeIdentifier node) {
|
||||
return root.contains(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(NodeIdentifier node) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<NodeIdentifier> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
28
ws2012/P2P/uebungen/11/src/util/BufferUtil.java
Normal file
28
ws2012/P2P/uebungen/11/src/util/BufferUtil.java
Normal file
@ -0,0 +1,28 @@
|
||||
package util;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class BufferUtil {
|
||||
|
||||
public static ByteBuffer clone(ByteBuffer original) {
|
||||
ByteBuffer clone = ByteBuffer.allocate(original.capacity());
|
||||
|
||||
int oldPosition = original.position();
|
||||
original.rewind();// copy from the beginning
|
||||
clone.put(original);
|
||||
// original.rewind();
|
||||
original.position(oldPosition);
|
||||
clone.flip();
|
||||
return clone;
|
||||
}
|
||||
|
||||
public static byte[] addrToBytes(InetSocketAddress addr) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(8);
|
||||
for (String part : addr.getHostString().split("\\.")) {
|
||||
buffer.put(Byte.valueOf(part));
|
||||
}
|
||||
buffer.putInt(addr.getPort());
|
||||
return buffer.array();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user