diff --git a/.gitignore b/.gitignore index ac30167e..690fa163 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ **/bin/** **/target/** **/tmp/** +**/.idea/** **/.metadata/** **/.settings/** **/.recommenders/** @@ -15,7 +16,7 @@ *.bak *.swp *~.nib - +/bin/ # Created by https://www.toptal.com/developers/gitignore/api/eclipse,java # Edit at https://www.toptal.com/developers/gitignore?templates=eclipse,java diff --git a/README_TESTING.md b/README_TESTING.md new file mode 100644 index 00000000..fbc8543b --- /dev/null +++ b/README_TESTING.md @@ -0,0 +1,38 @@ +# CodeMetropolis Test Phase + +## Getting started + +### Setup for SourceMeter analysis + +1. Download SourceMeter from its [webpage](https://sourcemeter.com/download). +2. Extract SourceMeter. +3. Download Minecraft Java version from its [webpage](https://www.minecraft.net/en-us/download). +4. Install Minecraft. +5. Optionally you could use the Minecraft starter to change the version of Minecraft to 1.8 (the officialy supported one), but newer versions could also open CodeMetropolis generated worlds. +6. Download the current [stable releas](https://github.com/codemetropolis/CodeMetropolis/releases/tag/latest) of CodeMetropolis. +7. Extract CodeMetropolis + +### Visualize source code meterics + +1. CodeMetropolis is able to visualize the static analysis results from SourceMeter. Currently Java is the most widely supported language. So to start, you have to locate a Java system, we will call this as target system. +2. Analyze the target system with SourceMeter. You could use any settings as long as it will produce a `graph` file. This graph file contains all the necessary data for the CodeMetropolis. +3. We will use the command line tools to create the visualization. + 1. Convert the data represented in the graph file into a more generic representations. Use the `converter` tool, with the sourcemeter conversion type option. It will produce an XML file which we call `CDF` file (Common Data Format) + 2. Create a `mapping XML` file to define the mapping between the properties of the source code items and the graphical attributes of CodeMetropolis. There is several sample files in this repository. + 3. Execute the `mapping` tool with the CDF file and the mapping XML to produce the first (yet incomplete) representation of the city. It will stored as an XML file we called `IXML` (Intermediate XML). + 4. The output of the `mapping` tool does not contain the placement and the size of the buildings. These data hava to be computed with the `placing` tool. + 5. In the final step we need to use the `rendering` tool to convert the final IXML file into a Minecraft world. +4. Installing the new visualization + 1. Start and close your Minecraft client (play the game) at least once to generate the necessary folder structure. + 2. Copy the generated world into the location of your saved worlds. On Windwos it is usually located under `C:\Users\\AppData\Roaming\.minecraft\saves`. You have to copy the whole folder not just its content. + 3. Start the game and select the world from the list. + +## Complie from source + +1. clone repository +1. checkout `develop` branch +1. install Java 1.8 +1. install Maven 3.8.3 or newer +1. navigate to `sources` folder +1. `mvn clean package` +1. The current distribution will be aviable under `source/distro`. diff --git a/dependencies/codemetropolis/cmblockmodifier/1.0.1/LICENSE.txt b/dependencies/codemetropolis/cmblockmodifier/1.0.1/LICENSE.txt deleted file mode 100644 index 54c07da9..00000000 --- a/dependencies/codemetropolis/cmblockmodifier/1.0.1/LICENSE.txt +++ /dev/null @@ -1 +0,0 @@ -This work is licensed under the Creative Commons Attribution 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/. \ No newline at end of file diff --git a/dependencies/codemetropolis/cmblockmodifier/1.0.1/_remote.repositories b/dependencies/codemetropolis/cmblockmodifier/1.0.1/_remote.repositories deleted file mode 100644 index 37c238ce..00000000 --- a/dependencies/codemetropolis/cmblockmodifier/1.0.1/_remote.repositories +++ /dev/null @@ -1,4 +0,0 @@ -#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice. -#Mon Jan 10 11:24:17 CET 2022 -cmblockmodifier-1.0.1.jar>= -cmblockmodifier-1.0.1.pom>= diff --git a/dependencies/codemetropolis/cmblockmodifier/1.0.1/cmblockmodifier-1.0.1.jar b/dependencies/codemetropolis/cmblockmodifier/1.0.1/cmblockmodifier-1.0.1.jar deleted file mode 100644 index ad74625a..00000000 Binary files a/dependencies/codemetropolis/cmblockmodifier/1.0.1/cmblockmodifier-1.0.1.jar and /dev/null differ diff --git a/dependencies/codemetropolis/cmblockmodifier/1.0.1/cmblockmodifier-1.0.1.pom b/dependencies/codemetropolis/cmblockmodifier/1.0.1/cmblockmodifier-1.0.1.pom deleted file mode 100644 index 90734043..00000000 --- a/dependencies/codemetropolis/cmblockmodifier/1.0.1/cmblockmodifier-1.0.1.pom +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - codemetropolis - cmblockmodifier - 1.0.1 - POM was created from install:install-file - diff --git a/dependencies/codemetropolis/cmblockmodifier/maven-metadata-local.xml b/dependencies/codemetropolis/cmblockmodifier/maven-metadata-local.xml deleted file mode 100644 index a12b4c9d..00000000 --- a/dependencies/codemetropolis/cmblockmodifier/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - codemetropolis - cmblockmodifier - - 1.0.1 - - 1.0.1 - - 20220110102415 - - diff --git a/examples/gitstats_input_example/Test/a.dat b/examples/gitstats_input_example/Test/a.dat new file mode 100644 index 00000000..5a5a738d --- /dev/null +++ b/examples/gitstats_input_example/Test/a.dat @@ -0,0 +1,2 @@ +elso 34 +masodik 56 \ No newline at end of file diff --git a/examples/gitstats_input_example/Test/b.dat b/examples/gitstats_input_example/Test/b.dat new file mode 100644 index 00000000..3a8dbeea --- /dev/null +++ b/examples/gitstats_input_example/Test/b.dat @@ -0,0 +1,2 @@ +harmadik 65 +negyedik 18 \ No newline at end of file diff --git a/examples/gitstats_input_example/activity.html b/examples/gitstats_input_example/activity.html new file mode 100644 index 00000000..712c77fa --- /dev/null +++ b/examples/gitstats_input_example/activity.html @@ -0,0 +1,616 @@ + + + + + GitStats - RF2 + + + + + +

Activity

+ +

Weekly activity

+

Last 32 weeks

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
3231302928272625242322212019181716151413121110987654321
+

Hour of Day

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Hour01234567891011121314151617181920212223
Commits0000000027177649883000302
%0.000.000.000.000.000.000.000.002.639.2122.379.217.895.2611.8410.5310.533.950.000.000.003.950.002.63
Hour of Day +

Day of Week

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DayTotal (%)
18 (10.53%)
26 (7.89%)
310 (13.16%)
431 (40.79%)
516 (21.05%)
62 (2.63%)
73 (3.95%)
Day of Week +

Hour of Week

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Weekday01234567891011121314151617181920212223
11121111
211121
312313
41310225422
523411311
611
712
+

Month of Year

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthCommits (%)
17 (9.21 %)
232 (42.11 %)
325 (32.89 %)
412 (15.79 %)
50 (0.00 %)
60 (0.00 %)
70 (0.00 %)
80 (0.00 %)
90 (0.00 %)
100 (0.00 %)
110 (0.00 %)
120 (0.00 %)
Month of Year +

Commits by + year/month

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthCommits
2017-022
2016-0411
2016-0325
2016-0230
2016-017
2014-041
Commits by year/month +

Commits by Year

+
+ + + + + + + + + + + + + + + + +
YearCommits (% of all)
20172 (2.63%)
201673 (96.05%)
20141 (1.32%)
Commits by Year +

Commits by Timezone

+ + + + + + + + + + + + + +
TimezoneCommits
+010056
+020020
+ \ No newline at end of file diff --git a/examples/gitstats_input_example/arrow-down.gif b/examples/gitstats_input_example/arrow-down.gif new file mode 100644 index 00000000..997f02f6 Binary files /dev/null and b/examples/gitstats_input_example/arrow-down.gif differ diff --git a/examples/gitstats_input_example/arrow-none.gif b/examples/gitstats_input_example/arrow-none.gif new file mode 100644 index 00000000..d011a499 Binary files /dev/null and b/examples/gitstats_input_example/arrow-none.gif differ diff --git a/examples/gitstats_input_example/arrow-up.gif b/examples/gitstats_input_example/arrow-up.gif new file mode 100644 index 00000000..15eabb35 Binary files /dev/null and b/examples/gitstats_input_example/arrow-up.gif differ diff --git a/examples/gitstats_input_example/authors.html b/examples/gitstats_input_example/authors.html new file mode 100644 index 00000000..86df0921 --- /dev/null +++ b/examples/gitstats_input_example/authors.html @@ -0,0 +1,167 @@ + + + + + GitStats - RF2 + + + + + +

Authors

+ +

List of Authors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AuthorCommits (%)+ lines- linesFirst commitLast commitAgeActive days# by commits
Attila Szabolics60 (78.95%)583522152016-01-172016-04-1487 days, 13:01:01221
berika11 (14.47%)14873492016-02-022016-03-0430 days, 23:03:5272
Gergő Balogh4 (5.26%)862014-04-082017-02-161045 days, 5:33:2033
Balogh Gergõ1 (1.32%)002016-01-182016-01-180:00:0014
+

Author of Month

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthAuthorCommits (%)Next top 5
2017-02Gergő Balogh2 (100.00% of 2)
2016-04Attila Szabolics11 (100.00% of 11)
2016-03Attila Szabolics22 (88.00% of 25)berika
2016-02Attila Szabolics22 (73.33% of 30)berika
2016-01Attila Szabolics5 (71.43% of 7)Gergő Balogh, Balogh Gergõ
2014-04Gergő Balogh1 (100.00% of 1)
+

Author of Year

+ + + + + + + + + + + + + + + + + + + + + + + + + +
YearAuthorCommits (%)Next top 5
2017Gergő Balogh2 (100.00% of 2)
2016Attila Szabolics60 (82.19% of 73)berika, Gergő Balogh, Balogh Gergõ
2014Gergő Balogh1 (100.00% of 1)
+

Commits by Domains

+
+ + + + + + + + + + + + +
DomainsTotal (%)
inf.u-szeged.hu72 (94.74%)
gmail.com4 (5.26%)
Commits by Domains + \ No newline at end of file diff --git a/examples/gitstats_input_example/commits_by_year.dat b/examples/gitstats_input_example/commits_by_year.dat new file mode 100644 index 00000000..31865f5a --- /dev/null +++ b/examples/gitstats_input_example/commits_by_year.dat @@ -0,0 +1,3 @@ +2014 1 +2016 73 +2017 2 \ No newline at end of file diff --git a/examples/gitstats_input_example/commits_by_year.plot b/examples/gitstats_input_example/commits_by_year.plot new file mode 100644 index 00000000..47cf23cf --- /dev/null +++ b/examples/gitstats_input_example/commits_by_year.plot @@ -0,0 +1,10 @@ +set terminal svg +set size 1.0,0.5 + +set output 'commits_by_year.svg' +unset key +set xtics 1 rotate by 90 +set grid y +set ylabel "Commits" +set yrange [0:] +plot 'commits_by_year.dat' using 1:2:(0.5) w boxes fs solid \ No newline at end of file diff --git a/examples/gitstats_input_example/commits_by_year_month.dat b/examples/gitstats_input_example/commits_by_year_month.dat new file mode 100644 index 00000000..0876773f --- /dev/null +++ b/examples/gitstats_input_example/commits_by_year_month.dat @@ -0,0 +1,6 @@ +2014-04 1 +2016-01 7 +2016-02 30 +2016-03 25 +2016-04 11 +2017-02 2 \ No newline at end of file diff --git a/examples/gitstats_input_example/commits_by_year_month.plot b/examples/gitstats_input_example/commits_by_year_month.plot new file mode 100644 index 00000000..ab421934 --- /dev/null +++ b/examples/gitstats_input_example/commits_by_year_month.plot @@ -0,0 +1,13 @@ +set terminal svg +set size 1.0,0.5 + +set output 'commits_by_year_month.svg' +unset key +set xdata time +set timefmt "%Y-%m" +set format x "%Y-%m" +set xtics rotate by 90 15768000 +set bmargin 5 +set grid y +set ylabel "Commits" +plot 'commits_by_year_month.dat' using 1:2:(0.5) w boxes fs solid \ No newline at end of file diff --git a/examples/gitstats_input_example/day_of_week.dat b/examples/gitstats_input_example/day_of_week.dat new file mode 100644 index 00000000..759470fe --- /dev/null +++ b/examples/gitstats_input_example/day_of_week.dat @@ -0,0 +1,7 @@ +1 8 +2 6 +3 10 +4 31 +5 16 +6 2 +7 3 \ No newline at end of file diff --git a/examples/gitstats_input_example/day_of_week.plot b/examples/gitstats_input_example/day_of_week.plot new file mode 100644 index 00000000..de5f4b64 --- /dev/null +++ b/examples/gitstats_input_example/day_of_week.plot @@ -0,0 +1,10 @@ +set terminal svg +set size 1.0,0.5 + +set output 'day_of_week.svg' +unset key +set xrange [0.5:7.5] +set xtics 1 +set grid y +set ylabel "Commits" +plot 'day_of_week.dat' using 1:2:(0.5) w boxes fs solid \ No newline at end of file diff --git a/examples/gitstats_input_example/domains.dat b/examples/gitstats_input_example/domains.dat new file mode 100644 index 00000000..eb675ace --- /dev/null +++ b/examples/gitstats_input_example/domains.dat @@ -0,0 +1,2 @@ +inf.u-szeged.hu 1 72 +gmail.com 2 4 \ No newline at end of file diff --git a/examples/gitstats_input_example/domains.plot b/examples/gitstats_input_example/domains.plot new file mode 100644 index 00000000..6951f2cd --- /dev/null +++ b/examples/gitstats_input_example/domains.plot @@ -0,0 +1,9 @@ +set terminal svg +set size 1.0,0.5 + +set output 'domains.svg' +unset key +unset xtics +set grid y +set ylabel "Commits" +plot 'domains.dat' using 2:3:(0.5) with boxes fs solid, '' using 2:3:1 with labels rotate by 45 offset 0,1 \ No newline at end of file diff --git a/examples/gitstats_input_example/files.html b/examples/gitstats_input_example/files.html new file mode 100644 index 00000000..4e4631b6 --- /dev/null +++ b/examples/gitstats_input_example/files.html @@ -0,0 +1,107 @@ + + + + + GitStats - RF2 + + + + + +

Files

+ +
+
Total files
+
164
+
Total lines
+
4205
+
Average file size
+
2564.02 bytes
+
+

File count by date

+ Files by Date +

Extensions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExtensionFiles (%)Lines (%)Lines/file
6 (3.66%)30 (0.71%)5
classpath5 (3.05%)178 (4.23%)35
csv1 (0.61%)170 (4.04%)170
jar2 (1.22%)355 (8.44%)177
java122 (74.39%)7925 (188.47%)64
md1 (0.61%)8 (0.19%)8
project6 (3.66%)132 (3.14%)22
properties2 (1.22%)93 (2.21%)46
txt4 (2.44%)864 (20.55%)216
xml13 (7.93%)2856 (67.92%)219
xsd1 (0.61%)49 (1.17%)49
+ \ No newline at end of file diff --git a/examples/gitstats_input_example/files_by_date.dat b/examples/gitstats_input_example/files_by_date.dat new file mode 100644 index 00000000..b1da0360 --- /dev/null +++ b/examples/gitstats_input_example/files_by_date.dat @@ -0,0 +1,46 @@ +2014-04-08 1 +2016-01-11 1 +2016-01-17 115 +2016-01-18 111 +2016-01-18 115 +2016-01-18 117 +2016-02-02 130 +2016-02-04 130 +2016-02-04 131 +2016-02-05 130 +2016-02-17 131 +2016-02-22 131 +2016-02-22 132 +2016-02-23 131 +2016-02-24 131 +2016-02-24 136 +2016-02-25 131 +2016-02-25 138 +2016-02-25 139 +2016-02-26 139 +2016-02-27 139 +2016-02-27 142 +2016-02-28 142 +2016-03-01 141 +2016-03-01 142 +2016-03-04 143 +2016-03-09 145 +2016-03-11 145 +2016-03-11 146 +2016-03-16 147 +2016-03-16 149 +2016-03-16 152 +2016-03-17 152 +2016-03-17 153 +2016-03-18 153 +2016-03-30 157 +2016-03-31 158 +2016-03-31 159 +2016-03-31 160 +2016-03-31 162 +2016-04-01 162 +2016-04-04 163 +2016-04-07 163 +2016-04-08 163 +2016-04-14 163 +2017-02-16 163 \ No newline at end of file diff --git a/examples/gitstats_input_example/files_by_date.plot b/examples/gitstats_input_example/files_by_date.plot new file mode 100644 index 00000000..5c5d15f7 --- /dev/null +++ b/examples/gitstats_input_example/files_by_date.plot @@ -0,0 +1,14 @@ +set terminal svg +set size 1.0,0.5 + +set output 'files_by_date.svg' +unset key +set xdata time +set timefmt "%Y-%m-%d" +set format x "%Y-%m-%d" +set grid y +set ylabel "Files" +set xtics rotate by 90 +set ytics autofreq +set bmargin 6 +plot 'files_by_date.dat' using 1:2 w steps \ No newline at end of file diff --git a/examples/gitstats_input_example/gitstats.cache b/examples/gitstats_input_example/gitstats.cache new file mode 100644 index 00000000..33ef9b0e Binary files /dev/null and b/examples/gitstats_input_example/gitstats.cache differ diff --git a/examples/gitstats_input_example/gitstats.css b/examples/gitstats_input_example/gitstats.css new file mode 100644 index 00000000..07922e6a --- /dev/null +++ b/examples/gitstats_input_example/gitstats.css @@ -0,0 +1,142 @@ +/** + * GitStats - default style + */ + body{ + color: black; + background-color: #dfd; +} + +dt{ + font-weight: bold; + float: left; + margin-right: 1em; +} + +dt:after{ + content: ': '; +} + +dd{ + display: block; + clear: left; +} + +table{ + border: 1px solid black; + border-collapse: collapse; + font-size: 80%; + margin-bottom: 1em; +} + +table.noborders{ + border: none; +} + +table.noborders td{ + border: none; +} + +.vtable{ + float: right; + clear: both; +} + +table.tags td{ + vertical-align: top; +} + +th{ + background-color: #ddf; +} + +th a{ + text-decoration: none; +} + +tr:hover{ + background-color: #ddf; +} + +td{ + border: 1px solid black; + padding: 0.2em; + padding-left: 0.3em; + padding-right: 0.2em; +} + +/* Navigation bar; tabbed style */ +.nav{ + border-bottom: 1px solid black; + padding: 0.3em; +} + +.nav ul{ + list-style-type: none; + display: inline; + margin: 0; + padding: 0; +} + +.nav li{ + display: inline; +} + +.nav li a{ + padding: 0.3em; + text-decoration: none; + color: black; + border: 1px solid black; + margin: 0.5em; + background-color: #ddf; +} + +.nav li a:hover{ + background-color: #ddd; + border-bottom: 1px solid #ddf; +} + +img{ + border: 1px solid black; + padding: 0.5em; + background-color: white; +} + +th img{ + border: 0px; + padding: 0px; + background-color: #ddf; +} + +h1 a, +h2 a{ + color: black; + text-decoration: none; +} + +h1:hover a:after, +h2:hover a:after{ + content: '¶'; + color: #555; +} + +h1{ + font-size: x-large; +} + +h2{ + background-color: #564; + border: 1px solid black; + padding-left: 0.5em; + padding-right: 0.5em; + color: white; + font-size: large; + clear: both; +} + +h2 a{ + color: white; +} + +.moreauthors{ + font-size: 80%; +} \ No newline at end of file diff --git a/examples/gitstats_input_example/hour_of_day.dat b/examples/gitstats_input_example/hour_of_day.dat new file mode 100644 index 00000000..cbf4a37c --- /dev/null +++ b/examples/gitstats_input_example/hour_of_day.dat @@ -0,0 +1,24 @@ +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 2 +10 7 +11 17 +12 7 +13 6 +14 4 +15 9 +16 8 +17 8 +18 3 +19 0 +20 0 +21 0 +22 3 +23 0 +24 2 \ No newline at end of file diff --git a/examples/gitstats_input_example/hour_of_day.plot b/examples/gitstats_input_example/hour_of_day.plot new file mode 100644 index 00000000..2b850a1c --- /dev/null +++ b/examples/gitstats_input_example/hour_of_day.plot @@ -0,0 +1,10 @@ +set terminal svg +set size 1.0,0.5 + +set output 'hour_of_day.svg' +unset key +set xrange [0.5:24.5] +set xtics 4 +set grid y +set ylabel "Commits" +plot 'hour_of_day.dat' using 1:2:(0.5) w boxes fs solid \ No newline at end of file diff --git a/examples/gitstats_input_example/index.html b/examples/gitstats_input_example/index.html new file mode 100644 index 00000000..23967085 --- /dev/null +++ b/examples/gitstats_input_example/index.html @@ -0,0 +1,42 @@ + + + + + GitStats - RF2 + + + + + +

GitStats - RF2

+ +
+
Project name
+
RF2
+
Generated
+
2018-03-22 09:49:02 (in 26 seconds)
+
Generator
+
GitStats (version 0432da3)
+
Report Period
+
2014-04-08 09:25:21 to 2017-02-16 14:58:41
+
Age
+
1046 days, 30 active days (2.87%)
+
Total Files
+
164
+
Total Lines of Code
+
4205 (6412 added, 2207 removed)
+
Total Commits
+
76 (average 2.5 commits per active day, 0.1 per all days)
+
Authors
+
4
+
+ \ No newline at end of file diff --git a/examples/gitstats_input_example/lines.html b/examples/gitstats_input_example/lines.html new file mode 100644 index 00000000..3143be60 --- /dev/null +++ b/examples/gitstats_input_example/lines.html @@ -0,0 +1,28 @@ + + + + + GitStats - RF2 + + + + + +

Lines

+ +
+
Total lines
+
4205
+
+

Lines of Code

+ + \ No newline at end of file diff --git a/examples/gitstats_input_example/lines_of_code.dat b/examples/gitstats_input_example/lines_of_code.dat new file mode 100644 index 00000000..9ad76ad2 --- /dev/null +++ b/examples/gitstats_input_example/lines_of_code.dat @@ -0,0 +1,76 @@ +1396941921 0 +1452504811 0 +1453060938 0 +1453068424 0 +1453102121 0 +1453104098 -217 +1453126093 -217 +1453130990 -217 +1454405253 442 +1454427553 434 +1454576709 434 +1454579063 462 +1454582958 431 +1454594118 401 +1454597133 415 +1454598586 415 +1454678086 415 +1454679615 415 +1455709118 518 +1456136886 582 +1456141544 2837 +1456242593 2874 +1456316164 2987 +1456327721 2990 +1456392069 3098 +1456392194 3098 +1456393248 3098 +1456409001 3076 +1456412351 3076 +1456416701 3062 +1456418280 3062 +1456484025 3074 +1456485496 3074 +1456489011 3074 +1456519663 3106 +1456580378 3156 +1456603758 3256 +1456696878 3276 +1456842492 3276 +1456849729 3399 +1457080285 3548 +1457533152 3595 +1457703860 3662 +1457707720 3713 +1458128143 3727 +1458131273 3739 +1458132805 3795 +1458141379 3795 +1458142029 3795 +1458204586 3814 +1458205356 3813 +1458222783 3880 +1458226862 3944 +1458292814 3944 +1458297739 3944 +1459327406 3921 +1459413328 3989 +1459414771 4010 +1459416626 4010 +1459418656 4058 +1459420073 4058 +1459426128 4063 +1459430029 4093 +1459498049 4088 +1459499948 4088 +1459502395 4106 +1459503115 4106 +1459758884 4185 +1460016249 4185 +1460101920 4197 +1460616408 4197 +1460619190 4204 +1460619943 4205 +1460620999 4205 +1487253511 4205 +1487253521 4205 \ No newline at end of file diff --git a/examples/gitstats_input_example/lines_of_code.plot b/examples/gitstats_input_example/lines_of_code.plot new file mode 100644 index 00000000..c925b16f --- /dev/null +++ b/examples/gitstats_input_example/lines_of_code.plot @@ -0,0 +1,13 @@ +set terminal svg +set size 1.0,0.5 + +set output 'lines_of_code.svg' +unset key +set xdata time +set timefmt "%s" +set format x "%Y-%m-%d" +set grid y +set ylabel "Lines" +set xtics rotate by 90 +set bmargin 6 +plot 'lines_of_code.dat' using 1:2 w lines \ No newline at end of file diff --git a/examples/gitstats_input_example/month_of_year.dat b/examples/gitstats_input_example/month_of_year.dat new file mode 100644 index 00000000..1a3e7f9f --- /dev/null +++ b/examples/gitstats_input_example/month_of_year.dat @@ -0,0 +1,12 @@ +1 7 +2 32 +3 25 +4 12 +5 0 +6 0 +7 0 +8 0 +9 0 +10 0 +11 0 +12 0 \ No newline at end of file diff --git a/examples/gitstats_input_example/month_of_year.plot b/examples/gitstats_input_example/month_of_year.plot new file mode 100644 index 00000000..bb2338c4 --- /dev/null +++ b/examples/gitstats_input_example/month_of_year.plot @@ -0,0 +1,10 @@ +set terminal svg +set size 1.0,0.5 + +set output 'month_of_year.svg' +unset key +set xrange [0.5:12.5] +set xtics 1 +set grid y +set ylabel "Commits" +plot 'month_of_year.dat' using 1:2:(0.5) w boxes fs solid \ No newline at end of file diff --git a/examples/gitstats_input_example/sortable.js b/examples/gitstats_input_example/sortable.js new file mode 100644 index 00000000..006a12f8 --- /dev/null +++ b/examples/gitstats_input_example/sortable.js @@ -0,0 +1,340 @@ +/* +Table sorting script by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/. +Based on a script from http://www.kryogenix.org/code/browser/sorttable/. +Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html . + +Copyright (c) 1997-2007 Stuart Langridge, Joost de Valk. + +Version 1.5.7 + */ + +/* You can change these values */ +var image_path = ""; +var image_up = "arrow-up.gif"; +var image_down = "arrow-down.gif"; +var image_none = "arrow-none.gif"; +var europeandate = true; +var alternate_row_colors = true; + +/* Don't change anything below this unless you know what you're doing */ +addEvent(window, "load", sortables_init); + +var SORT_COLUMN_INDEX; +var thead = false; + +function sortables_init() { + // Find all tables with class sortable and make them sortable + if (! document.getElementsByTagName) return; + tbls = document.getElementsByTagName("table"); + for (ti = 0; ti < tbls.length; ti++) { + thisTbl = tbls[ti]; + if (((' ' + thisTbl.className + ' ').indexOf("sortable") != -1) && (thisTbl.id)) { + ts_makeSortable(thisTbl); + } + } +} + +function ts_makeSortable(t) { + if (t.rows && t.rows.length > 0) { + if (t.tHead && t.tHead.rows.length > 0) { + var firstRow = t.tHead.rows[t.tHead.rows.length -1]; + thead = true; + } else { + var firstRow = t.rows[0]; + } + } + if (! firstRow) return; + + // We have a first row: assume it's the header, and make its contents clickable links + for (var i = 0; i < firstRow.cells.length; i++) { + var cell = firstRow.cells[i]; + var txt = ts_getInnerText(cell); + if (cell.className != "unsortable" && cell.className.indexOf("unsortable") == -1) { + cell.innerHTML = '' + txt + '  ↓'; + } + } + if (alternate_row_colors) { + alternate(t); + } +} + +function ts_getInnerText(el) { + if (typeof el == "string") return el; + if (typeof el == "undefined") { + return el + }; + if (el.innerText) return el.innerText; + //Not needed but it is faster + var str = ""; + + var cs = el.childNodes; + var l = cs.length; + for (var i = 0; i < l; i++) { + switch (cs[i].nodeType) { + case 1: //ELEMENT_NODE + str += ts_getInnerText(cs[i]); + break; + case 3: //TEXT_NODE + str += cs[i].nodeValue; + break; + } + } + return str; +} + +function ts_resortTable(lnk, clid) { + var span; + for (var ci = 0; ci < lnk.childNodes.length; ci++) { + if (lnk.childNodes[ci].tagName && lnk.childNodes[ci].tagName.toLowerCase() == 'span') span = lnk.childNodes[ci]; + } + var spantext = ts_getInnerText(span); + var td = lnk.parentNode; + var column = clid || td.cellIndex; + var t = getParent(td, 'TABLE'); + // Work out a type for the column + if (t.rows.length <= 1) return; + var itm = ""; + var i = 1; + while (itm == "" && i < t.tBodies[0].rows.length) { + var itm = ts_getInnerText(t.tBodies[0].rows[i].cells[column]); + itm = trim(itm); + if (itm.substr(0, 4) == " + + junit + junit + test + \ No newline at end of file diff --git a/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/Buildable.java b/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/Buildable.java index 6ce6fda9..e6752b68 100644 --- a/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/Buildable.java +++ b/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/Buildable.java @@ -16,7 +16,9 @@ public enum Type { GARDEN, FLOOR, CELLAR, - CONTAINER; + CONTAINER, + TUNNEL, + BRIDGE; } private String id; @@ -28,6 +30,9 @@ public enum Type { private List children; private Buildable parent; private String cdfNames; + private boolean hasLowerStairs; + private boolean hasUpperStairs; + private int BuiltMetric1, BuiltMetric2, BuiltMetric3; public Buildable(String id, String name, Type type) { this(id, name, type, new Point(), new Point()); @@ -41,6 +46,8 @@ public Buildable(String id, String name, Type type, Point position, Point size) this.size = size; this.attributes = new ArrayList(); this.children = new ArrayList(); + this.setHasLowerStairs(false); + this.setHasUpperStairs(false); } public boolean isOverlapping(Buildable b) { @@ -310,6 +317,30 @@ public void setSizeZ(int z) { size.setZ(z); } + public int getBuiltMetric1() { + return BuiltMetric1; + } + + public void setBuiltMetric1(int builtMetric1) { + BuiltMetric1 = builtMetric1; + } + + public int getBuiltMetric2() { + return BuiltMetric2; + } + + public void setBuiltMetric2(int builtMetric2) { + BuiltMetric2 = builtMetric2; + } + + public int getBuiltMetric3() { + return BuiltMetric3; + } + + public void setBuiltMetric3(int builtMetric3) { + BuiltMetric3 = builtMetric3; + } + public Attribute[] getAttributes() { return attributes.toArray(new Attribute[attributes.size()]); } @@ -460,4 +491,22 @@ public Element toXmlElement(Document doc, boolean recursive) { return buildable; } + + public boolean hasLowerStairs() { + return hasLowerStairs; + } + + public void setHasLowerStairs(boolean hasLowerStairs) { + this.hasLowerStairs = hasLowerStairs; + } + + public boolean hasUpperStairs() { + return hasUpperStairs; + } + + public void setHasUpperStairs(boolean hasUpperStairs) { + this.hasUpperStairs = hasUpperStairs; + } + + } \ No newline at end of file diff --git a/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/BuildableTree.java b/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/BuildableTree.java index 06ebe60b..0c61f223 100644 --- a/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/BuildableTree.java +++ b/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/BuildableTree.java @@ -132,6 +132,10 @@ public void loadFromFile(String path) throws CmxmlReaderException { break; case "container": type = Type.CONTAINER; break; + case "tunnel": type = Type.TUNNEL; + break; + case "bridge": type = Type.BRIDGE; + break; } Point position; @@ -148,11 +152,12 @@ public void loadFromFile(String path) throws CmxmlReaderException { Point size; if(eElement.getElementsByTagName("size").item(0) != null && eElement.getElementsByTagName("size").item(0).getParentNode() == nNode) { size = new Point( - Integer.parseInt(((Element)eElement.getElementsByTagName("size").item(0)).getAttribute("x")), - Integer.parseInt(((Element)eElement.getElementsByTagName("size").item(0)).getAttribute("y")), - Integer.parseInt(((Element)eElement.getElementsByTagName("size").item(0)).getAttribute("z")) - ); - } else { + Integer.parseInt(((Element) eElement.getElementsByTagName("size").item(0)).getAttribute("x")), + Integer.parseInt(((Element) eElement.getElementsByTagName("size").item(0)).getAttribute("y")), + Integer.parseInt(((Element) eElement.getElementsByTagName("size").item(0)).getAttribute("z")) + ); + } + else { size = new Point(); } diff --git a/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/Point.java b/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/Point.java index dd3fa473..18c5ba78 100644 --- a/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/Point.java +++ b/sources/commons/src/main/java/codemetropolis/toolchain/commons/cmxml/Point.java @@ -48,5 +48,40 @@ public int getZ() { protected void setZ(int z) { this.z = z; } + + @Override + public String toString() { + return "Point [x=" + x + ", y=" + y + ", z=" + z + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + x; + result = prime * result + y; + result = prime * result + z; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Point other = (Point) obj; + if (x != other.x) + return false; + if (y != other.y) + return false; + if (z != other.z) + return false; + return true; + } + + } diff --git a/sources/commons/src/main/resources/resources.properties b/sources/commons/src/main/resources/resources.properties index 83de1655..bd46b560 100644 --- a/sources/commons/src/main/resources/resources.properties +++ b/sources/commons/src/main/resources/resources.properties @@ -3,6 +3,7 @@ error_prefix = Error: converter_prefix = Converter: mapping_prefix = Mapping: placing_prefix = Placing: +metrics_prefix = Metrics processing: rendering_prefix = Rendering: # Converter info @@ -46,9 +47,13 @@ calculating_size_and_pos_done = Calculating building sizes and positions done. placing_printing_output = Generating input for rendering... placing_printing_output_done = Generating input for rendering done. +# Metrics processing notifications +metrics_generating_began = Generating metrics for display... +metrics_generating_done = Metrics created. + # Rendering info rendering_introduction = CodeMetropolis Toolchain Rendering (c) University of Szeged, Department of Software Engineering -rendering_usage = Usage: java -jar rendering.jar -i -world +rendering_usage = Usage: java -jar rendering.jar -i -world [-t ] # Rendering notifications world_already_exists = Another world with the same name might exist or being built right now. Do you want to overwrite? [Y/N] @@ -88,4 +93,6 @@ invalid_scale_error = Scale value must be between %.2f and %.2f. invalid_converter_type = Converter with the given identifier does not exist. invalid_params = Invalid parameter format. sonar_connect_error = Could not connect to SonarQube server. -sonar_unauthorized_error = Unauthorized server access. Please provide your username and password in converter parameters if you are accessing a non-public SonarQube resource. \ No newline at end of file +sonar_unauthorized_error = Unauthorized server access. Please provide your username and password in converter parameters if you are accessing a non-public SonarQube resource. +sourcemeter_only_error = Only SourceMeter metrics are allowed for the in-game display. +xml_not_found = XML not found, expected location: \ No newline at end of file diff --git a/sources/commons/src/main/resources/settings.properties b/sources/commons/src/main/resources/settings.properties index 1b8e4bd5..212477a5 100644 --- a/sources/commons/src/main/resources/settings.properties +++ b/sources/commons/src/main/resources/settings.properties @@ -1,4 +1,4 @@ converter_log_file = CodeMetropolis_toolchain.log mapping_log_file = CodeMetropolis_toolchain.log -placing_log_file = CodeMetropolis_toolchain.log +placing_log_file = CodeMetropolis_toolchain.logmetrics_log_file = CodeMetropolis_toolchain.log rendering_log_file = CodeMetropolis_toolchain.log \ No newline at end of file diff --git a/sources/commons/src/test/java/codemetropolis/toolchain/commons/cmxml/BuildableTest.java b/sources/commons/src/test/java/codemetropolis/toolchain/commons/cmxml/BuildableTest.java new file mode 100644 index 00000000..f8a33725 --- /dev/null +++ b/sources/commons/src/test/java/codemetropolis/toolchain/commons/cmxml/BuildableTest.java @@ -0,0 +1,26 @@ +package codemetropolis.toolchain.commons.cmxml; + +import codemetropolis.toolchain.commons.cmxml.Buildable.Type; +import junit.framework.TestCase; + +public class BuildableTest extends TestCase { + + Buildable b1, b2, b3; + + public void setup() { + b1 = null; + b2 = null; + b3 = null; + } + + public void testIsOverlapping() { + b1 = new Buildable("test1", "testBuilding1", Type.FLOOR, new Point(0, 0, 0), new Point(2, 2, 2)); + b2 = new Buildable("test2", "testBuilding2", Type.FLOOR, new Point(1, 1, 1), new Point(2, 2, 2)); + b3 = new Buildable("test3", "testBuilding3", Type.FLOOR, new Point(-1, -1, -1), new Point(2, 2, 2)); + + assertTrue(b1.isOverlapping(b2)); + assertTrue(b3.isOverlapping(b1)); + assertFalse(b2.isOverlapping(b3)); + } + +} diff --git a/sources/commons/src/test/java/codemetropolis/toolchain/commons/cmxml/PointTest.java b/sources/commons/src/test/java/codemetropolis/toolchain/commons/cmxml/PointTest.java new file mode 100644 index 00000000..c98c8a8a --- /dev/null +++ b/sources/commons/src/test/java/codemetropolis/toolchain/commons/cmxml/PointTest.java @@ -0,0 +1,23 @@ +package codemetropolis.toolchain.commons.cmxml; + +import junit.framework.TestCase; + +public class PointTest extends TestCase { + + Point testObj; + + public void setup() { + testObj = null; + } + + public void testTranslate() { + testObj = new Point(0, 0, 0); + + Point newPoint = testObj.translate(new Point(1, 2, 3)); + + assertEquals(1, newPoint.getX()); + assertEquals(2, newPoint.getY()); + assertEquals(3, newPoint.getZ()); + } + +} diff --git a/sources/commons/src/test/java/codemetropolis/toolchain/commons/util/TimeTest.java b/sources/commons/src/test/java/codemetropolis/toolchain/commons/util/TimeTest.java new file mode 100644 index 00000000..1ab330aa --- /dev/null +++ b/sources/commons/src/test/java/codemetropolis/toolchain/commons/util/TimeTest.java @@ -0,0 +1,58 @@ +package codemetropolis.toolchain.commons.util; + +import junit.framework.TestCase; + +public class TimeTest extends TestCase { + + Time testObj; + + public void setup() { + testObj = null; + } + + public void testGetHours() { + testObj = new Time(0); + assertEquals(0, testObj.getHours()); + + testObj = new Time(3599999); // 0 hrs 59 mins 59 seconds, 999 milliseconds + assertEquals(0, testObj.getHours()); + + testObj = new Time(86400001); // 24 hrs 1 milliseconds + assertEquals(24, testObj.getHours()); + } + + public void testGetMinutes() { + testObj = new Time(0); + assertEquals(0, testObj.getMinutes()); + + testObj = new Time(6999); + assertEquals(0, testObj.getMinutes()); + + testObj = new Time(59999); + assertEquals(0, testObj.getMinutes()); + + testObj = new Time(60000); + assertEquals(1, testObj.getMinutes()); + + testObj = new Time(3600000); + assertEquals(0, testObj.getMinutes()); + + testObj = new Time(3730000); + assertEquals(2, testObj.getMinutes()); + } + + public void testGetSeconds() { + testObj = new Time(0); + assertEquals(0, testObj.getSeconds()); + + testObj = new Time(3999); + assertEquals(3, testObj.getSeconds()); + + testObj = new Time(60000); + assertEquals(0, testObj.getSeconds()); + + testObj = new Time(74500); + assertEquals(14, testObj.getSeconds()); + } + +} diff --git a/sources/commons/test/codemetropolis/toolchain/commons/cmxml/comparators/BuildableDepthComparatorTest.java b/sources/commons/test/codemetropolis/toolchain/commons/cmxml/comparators/BuildableDepthComparatorTest.java new file mode 100644 index 00000000..a2cc2fc6 --- /dev/null +++ b/sources/commons/test/codemetropolis/toolchain/commons/cmxml/comparators/BuildableDepthComparatorTest.java @@ -0,0 +1,33 @@ +package codemetropolis.toolchain.commons.cmxml.comparators; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import codemetropolis.toolchain.commons.cmxml.Buildable; +import codemetropolis.toolchain.commons.cmxml.Buildable.Type; +import codemetropolis.toolchain.commons.cmxml.Point; + +/** Test class for {@link Tunnel}, to test depth comparator. + * + * @author Csuvik Viktor {@literal D1YZL5} + * @version %I% + * + */ + +public class BuildableDepthComparatorTest { + + @Test + public void testCompare() { + BuildableDepthComparator c = new BuildableDepthComparator(); + Buildable b1 = new Buildable("UNIQUE_ID_1", "SAMPLE_TUNNEL_1", Type.TUNNEL, new Point(0, 0, 0), new Point(10, 10, 10)); + Buildable b2 = new Buildable("UNIQUE_ID_2", "SAMPLE_TUNNEL_2", Type.TUNNEL, new Point(0, 0, 0), new Point(10, 10, 10)); + assertTrue(c.compare(b1, b2) == 0); + + Buildable b3 = new Buildable("UNIQUE_ID_3", "SAMPLE_TUNNEL_3", Type.TUNNEL, new Point(0, 0, 0), new Point(15, 15, 15)); + assertTrue(c.compare(b1, b3) != 0); + + Buildable b4 = new Buildable("UNIQUE_ID_4", "SAMPLE_GARDEN_1", Type.GARDEN, new Point(0, 0, 0), new Point(10, 10, 10)); + assertTrue(c.compare(b1, b4) == 0); + } +} diff --git a/sources/commons/test/codemetropolis/toolchain/commons/cmxml/comparators/BuildableSizeComparatorTest.java b/sources/commons/test/codemetropolis/toolchain/commons/cmxml/comparators/BuildableSizeComparatorTest.java new file mode 100644 index 00000000..d26a620c --- /dev/null +++ b/sources/commons/test/codemetropolis/toolchain/commons/cmxml/comparators/BuildableSizeComparatorTest.java @@ -0,0 +1,37 @@ + +package codemetropolis.toolchain.commons.cmxml.comparators; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import codemetropolis.toolchain.commons.cmxml.Buildable; +import codemetropolis.toolchain.commons.cmxml.Point; +import codemetropolis.toolchain.commons.cmxml.Buildable.Type; + +/** Test class for {@link Tunnel}, to test size comparator. + * + * @author Csuvik Viktor {@literal D1YZL5} + * @version %I% + * + */ + + +public class BuildableSizeComparatorTest { + + @Test + public void testCompare() { + BuildableSizeComparator c = new BuildableSizeComparator(); + Buildable b1 = new Buildable("UNIQUE_ID_1", "SAMPLE_TUNNEL_1", Type.TUNNEL, new Point(0, 0, 0), new Point(10, 10, 10)); + Buildable b2 = new Buildable("UNIQUE_ID_2", "SAMPLE_TUNNEL_2", Type.TUNNEL, new Point(0, 0, 0), new Point(10, 10, 10)); + assertTrue(c.compare(b1, b2) == 0); + + Buildable b3 = new Buildable("UNIQUE_ID_3", "SAMPLE_TUNNEL_3", Type.TUNNEL, new Point(0, 0, 0), new Point(15, 15, 15)); + assertTrue(c.compare(b1, b3) != 0); + + Buildable b4 = new Buildable("UNIQUE_ID_4", "SAMPLE_GARDEN_1", Type.GARDEN, new Point(0, 0, 0), new Point(10, 10, 10)); + assertTrue(c.compare(b1, b4) == 0); + } + +} + diff --git a/sources/distro/desktop.ini b/sources/distro/desktop.ini new file mode 100644 index 00000000..32320737 --- /dev/null +++ b/sources/distro/desktop.ini @@ -0,0 +1,2 @@ +[LocalizedFileNames] +bugok.txt=@bugok,0 diff --git a/sources/gui/.project b/sources/gui/.project index a7ab247e..d11a9317 100644 --- a/sources/gui/.project +++ b/sources/gui/.project @@ -20,4 +20,4 @@ org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature - + \ No newline at end of file diff --git a/sources/gui/pom.xml b/sources/gui/pom.xml index ec209eac..128b01c7 100644 --- a/sources/gui/pom.xml +++ b/sources/gui/pom.xml @@ -23,13 +23,34 @@ codemetropolis.toolchain.gui.Main + true + lib/ + + . + org.apache.maven.plugins maven-dependency-plugin + + + copy-dependencies + package + + copy-dependencies + + + ${project.build.directory}/lib + false + false + true + junit + + + @@ -60,5 +81,10 @@ rendering ${project.version} + + junit + junit + test + diff --git a/sources/gui/src/main/java/codemetropolis/toolchain/gui/CodeMetropolisGUI.java b/sources/gui/src/main/java/codemetropolis/toolchain/gui/CodeMetropolisGUI.java index 7ef2ae8a..2f2e448d 100644 --- a/sources/gui/src/main/java/codemetropolis/toolchain/gui/CodeMetropolisGUI.java +++ b/sources/gui/src/main/java/codemetropolis/toolchain/gui/CodeMetropolisGUI.java @@ -9,7 +9,6 @@ import java.io.File; import java.io.PipedOutputStream; import java.util.Random; - import javax.swing.ImageIcon; import javax.swing.JFileChooser; import javax.swing.JFrame; @@ -18,7 +17,6 @@ import javax.swing.JTabbedPane; import javax.swing.SwingConstants; import javax.swing.filechooser.FileFilter; - import codemetropolis.toolchain.gui.beans.ExecutionOptions; import codemetropolis.toolchain.gui.components.CMButton; import codemetropolis.toolchain.gui.components.CMCheckBox; @@ -33,7 +31,6 @@ import codemetropolis.toolchain.gui.utils.Translations; import codemetropolis.toolchain.gui.utils.XmlFileFilter; import codemetropolis.toolchain.placing.layout.LayoutAlgorithm; - /** * GUI window for the CodeMetropolis toolchain. * @@ -202,13 +199,13 @@ private final void addMappingOptions(JPanel panel) { mappingPath = new CMTextField(145, 555, 235, 30); CMButton mappingBrowse = new CMButton(Translations.t("gui_b_browse"), 385, 555, 100, 30); mappingBrowse.addActionListener(new BrowseListener(mappingPath, JFileChooser.FILES_ONLY, XML_FILTER)); - + CMLabel scaleLabel = new CMLabel(Translations.t("gui_l_scale"), 15, 590, 120, 30); scaleSpinner = new CMSpinner(145, 590, 120, 30); validateStructure = new CMCheckBox(275, 590, 20, 30); CMLabel validateStructureLabel = new CMLabel(Translations.t("gui_l_validate_structure"), 300, 590, 185, 30); - + panel.add(mappingLabel); panel.add(mappingPath); panel.add(mappingBrowse); diff --git a/sources/gui/src/main/java/codemetropolis/toolchain/gui/GUIController.java b/sources/gui/src/main/java/codemetropolis/toolchain/gui/GUIController.java index 3c512a63..dd4d5298 100644 --- a/sources/gui/src/main/java/codemetropolis/toolchain/gui/GUIController.java +++ b/sources/gui/src/main/java/codemetropolis/toolchain/gui/GUIController.java @@ -6,7 +6,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; - import codemetropolis.toolchain.gui.beans.ExecutionException; import codemetropolis.toolchain.gui.beans.ExecutionOptions; import codemetropolis.toolchain.gui.components.CMMetricPanel; diff --git a/sources/gui/src/main/java/codemetropolis/toolchain/gui/beans/ExecutionOptions.java b/sources/gui/src/main/java/codemetropolis/toolchain/gui/beans/ExecutionOptions.java index 33f2523a..dfa8481a 100644 --- a/sources/gui/src/main/java/codemetropolis/toolchain/gui/beans/ExecutionOptions.java +++ b/sources/gui/src/main/java/codemetropolis/toolchain/gui/beans/ExecutionOptions.java @@ -108,7 +108,7 @@ public void setValidate(boolean validate) { public void setLayoutAlgorithm(LayoutAlgorithm layoutAlgorithm) { this.layoutAlgorithm = layoutAlgorithm; } - + public void setShowMap(boolean showMap) { this.showMap = showMap; } diff --git a/sources/gui/src/main/java/codemetropolis/toolchain/gui/components/listeners/BrowseListener.java b/sources/gui/src/main/java/codemetropolis/toolchain/gui/components/listeners/BrowseListener.java index 9e4776d7..a786c256 100644 --- a/sources/gui/src/main/java/codemetropolis/toolchain/gui/components/listeners/BrowseListener.java +++ b/sources/gui/src/main/java/codemetropolis/toolchain/gui/components/listeners/BrowseListener.java @@ -35,7 +35,7 @@ public BrowseListener(CMTextField fileNameTextField, int fileSelectionMode, File this.fileChooser.setFileFilter(filter); } } - + @Override public void actionPerformed(ActionEvent event) { if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { diff --git a/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/ExeFileFilterTest.java b/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/ExeFileFilterTest.java index 0b431885..1aebe1bf 100644 --- a/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/ExeFileFilterTest.java +++ b/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/ExeFileFilterTest.java @@ -1,13 +1,11 @@ package codemetropolis.toolchain.gui.utils; -import static org.junit.jupiter.api.Assertions.assertEquals; - import java.io.File; import java.io.IOException; import java.nio.file.Files; -import org.junit.jupiter.api.Test; - +import org.junit.Assert; +import org.junit.Test; /** * Test class for testing the {@link ExeFileFilter} for properly accepting and filtering files. @@ -27,7 +25,7 @@ public class ExeFileFilterTest { public void testAcceptExeFile() throws IOException { File tempFile = File.createTempFile("test", ".exe"); boolean result = instance.accept(tempFile); - assertEquals(result, true); + Assert.assertEquals(result, true); } /** @@ -39,7 +37,7 @@ public void testAcceptExeFile() throws IOException { public void testAcceptNonExeFile() throws IOException { File tempFile = File.createTempFile("test", ".xml"); boolean result = instance.accept(tempFile); - assertEquals(result, false); + Assert.assertEquals(result, false); } /** @@ -51,7 +49,7 @@ public void testAcceptNonExeFile() throws IOException { public void testAcceptDirectory() throws IOException { File tempFolder = Files.createTempDirectory("test").toFile(); boolean result = instance.accept(tempFolder); - assertEquals(result, true); + Assert.assertEquals(result, true); } -} +} \ No newline at end of file diff --git a/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/GuiUtilsTest.java b/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/GuiUtilsTest.java index bf27d2c1..1ca09943 100644 --- a/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/GuiUtilsTest.java +++ b/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/GuiUtilsTest.java @@ -1,10 +1,10 @@ package codemetropolis.toolchain.gui.utils; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.Assert.*; import java.io.File; -import org.junit.jupiter.api.Test; +import org.junit.Test; /** * Test class for GuiUtils. Automatically find minecraft root on the computer diff --git a/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/XmlFileFilterTest.java b/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/XmlFileFilterTest.java index 773b09f1..7522362c 100644 --- a/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/XmlFileFilterTest.java +++ b/sources/gui/src/test/java/codemetropolis/toolchain/gui/utils/XmlFileFilterTest.java @@ -1,13 +1,11 @@ package codemetropolis.toolchain.gui.utils; -import static org.junit.jupiter.api.Assertions.assertEquals; - import java.io.File; import java.io.IOException; import java.nio.file.Files; -import org.junit.jupiter.api.Test; - +import org.junit.Assert; +import org.junit.Test; /** * Test class for testing the {@link XmlFileFilter} for properly accepting and filtering files. @@ -27,7 +25,7 @@ public class XmlFileFilterTest { public void testAcceptXmlFile() throws IOException { File tempFile = File.createTempFile("test", ".xml"); boolean result = instance.accept(tempFile); - assertEquals(result, true); + Assert.assertEquals(result, true); } /** @@ -39,7 +37,7 @@ public void testAcceptXmlFile() throws IOException { public void testAcceptNonXmlFile() throws IOException { File tempFile = File.createTempFile("test", ".txt"); boolean result = instance.accept(tempFile); - assertEquals(result, false); + Assert.assertEquals(result, false); } /** @@ -51,7 +49,7 @@ public void testAcceptNonXmlFile() throws IOException { public void testAcceptDirectory() throws IOException { File tempFolder = Files.createTempDirectory("test").toFile(); boolean result = instance.accept(tempFolder); - assertEquals(result, true); + Assert.assertEquals(result, true); } -} +} \ No newline at end of file diff --git a/sources/pom.xml b/sources/pom.xml index 022749a7..0401b0cb 100644 --- a/sources/pom.xml +++ b/sources/pom.xml @@ -41,8 +41,13 @@ org.junit.jupiter junit-jupiter-api - 5.8.1 - test + 5.9.1 + + + junit + junit + 4.12 + @@ -59,14 +64,6 @@ file://${user.dir}/../dependencies - - - - org.junit.jupiter - junit-jupiter-api - test - - @@ -152,4 +149,23 @@ + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.7 + + + false + + + + + org.codehaus.mojo + emma-maven-plugin + 1.2 + + + \ No newline at end of file diff --git a/sources/test/CodeMetropolis Tester Interface.py b/sources/test/CodeMetropolis Tester Interface.py new file mode 100644 index 00000000..3aec58da --- /dev/null +++ b/sources/test/CodeMetropolis Tester Interface.py @@ -0,0 +1,378 @@ +import tkinter as tk +from tkinter import * +from PIL import Image, ImageTk +import subprocess +import os +import io +from tkinter import StringVar +from tkinter import filedialog +from tkinter import ttk + +entries = [] +entries_converter = [] +entries_mapping = [] +config_dict = {} +lang_dict = {} +program_name = "CodeMetropolis Tester Interface" +program_name_full = "CodeMetropolis Tester Interface.py" +program_version = " v1.2" +tk_window_size = "1000x600" +tester_file_name = "\"CodeMetropolis Tester.py\"" +def_font = ("Helvetica", 10) +page_font = ("Helvetica", 12, "bold") +program_icon_path = 'config/icon.ico' +program_logo_path = "config/logo_transparent.png" +last_textbox_inputs_file_path = "config/textbox_last_input.txt" +config_file_path = "config/config.txt" +eng_lang_file_path = "config/english_language_file.txt" +hun_lang_file_path = "config/hungarian_language_file.txt" +default_config_lines = "language=eng\ntheme=light" + +def defaultConfigWriter(): + c = open(config_file_path, "w+") + c.write(default_config_lines) + c.close() + +#load file functon +def loadTxtFile(file_path): + lines_dict = {} + with io.open(file_path, mode="r", encoding="utf-8") as f: + lines = f.readlines() + + for line in lines: + line_parts = line.split("=") + lines_dict[line_parts[0]] = line_parts[1].strip() + return lines_dict + +config_dict = loadTxtFile(config_file_path) + +#theme set +if config_dict["theme"] == "dark": + BG_COLOR = "#121212" + FONT_COLOR = "#FFFFFF" + BTN_COLOR = "#BB86FC" +else: + BG_COLOR = "#DEE4E7" + FONT_COLOR = "#000000" + BTN_COLOR = "#FFFFFF" + +lang_dict = loadTxtFile(eng_lang_file_path) +if config_dict["language"] == "hun": + lang_dict = loadTxtFile(hun_lang_file_path) + +ABOUT_TXT = lang_dict["Desc"] + "\n\n" + lang_dict["MadeBy"] + "\n" + lang_dict["MadeYear"] +HOW_TO_TXT = lang_dict["Step1"] + "\n\n" + lang_dict["Step2"] + "\n\n" + lang_dict["Step3"] + "\n\n" + lang_dict["Step4"] + "\n\n" + lang_dict["Step5"] + "\n\n" + lang_dict["Step6"] + "\n\n" + lang_dict["Step7"] + "\n\n" + lang_dict["Step8"] + "\n\n" + lang_dict["Step9"] + +#choose file button function +def selectFile(entry): + file_path = filedialog.askopenfilename() + entry.delete(0, tk.END) + entry.insert(0, file_path) + +#choose folder button function +def selectFolder(entry): + folder_path = filedialog.askdirectory() + entry.delete(0, tk.END) + entry.insert(0, folder_path) + +#refresh function +def refreshApp(self): + self.destroy() + os.startfile(program_name_full) + +#the interface is separated from the testing execution so all arguments will be given to a tester file +def CmdCommand(): + arg1 = entries[0].get() + arg2 = entries[1].get() + arg3 = entries[2].get() + arg4 = entries[3].get() + + cmd = f"{tester_file_name} {arg1} {arg2} {arg3} {arg4}" + + #if selected tool converter, you can add type and parameters values + if len(entries_converter) == 2: + arg5 = "--type " + entries_converter[0].get() + if not entries_converter[1].get().strip(): + arg6 = "--parameters " + "None" + else: + arg6 = "--parameters " + entries_converter[1].get() + + cmd += f" {arg5} {arg6}" + + #if selected tool mapping, you need to add Metrics assign file value + if len(entries_mapping) == 1: + arg5 = "--mapping_file_path " + entries_mapping[0].get() + cmd += f" {arg5}" + + subprocess.call(cmd, shell=True) + print(cmd) + + +class App(tk.Tk): + def __init__(self): + super().__init__() + self.geometry(tk_window_size) + self.title( program_name + program_version) + self.resizable(width=False, height=False) + self.iconbitmap(program_icon_path) + image = Image.open(program_logo_path) + image = image.resize((150, 150)) + logo = ImageTk.PhotoImage(image) + + gridNSEW = {"padx": 10, "pady": 10, "sticky": "nsew"} + gridEW = {"padx": 10, "pady": 10, "sticky": "ew"} + color_font = {"bg": BG_COLOR, "fg": FONT_COLOR, "font": def_font} + button_font = {"bg": BTN_COLOR, "fg": FONT_COLOR, "font": def_font} + + def configWriter(): + c = open(config_file_path, "w+") + c.write(list(config_dict.keys())[0] + "=" + config_dict["language"] + "\n" + list(config_dict.keys())[1] + "=" + config_dict["theme"] + "\n") + c.close() + refreshApp(self) + + def changeTheme(selected_mode): + if (selected_mode == lang_dict["Dark"]): + config_dict["theme"] = "dark" + else: + config_dict["theme"] = "light" + configWriter() + + def changeLanguage(selected_language): + match selected_language: + case str(selected_language) if lang_dict["Magyar"] in selected_language: + config_dict["language"] = "hun" + case _: + config_dict["language"] = "eng" + configWriter() + + #MENU + menubar = tk.Menu(self) + #Tool menu + file_menu = tk.Menu(menubar, tearoff=0) + + file_menu.add_command(label=lang_dict["Converter"], command=lambda: (changeMainPage(lang_dict["ConverterTool"]))) + file_menu.add_command(label=lang_dict["Mapping"], command=lambda: (changeMainPage(lang_dict["MappingTool"]))) + file_menu.add_command(label=lang_dict["Placing"], command=lambda: (changeMainPage(lang_dict["PlacingTool"]))) + file_menu.add_command(label=lang_dict["Rendering"], command=lambda: (changeMainPage(lang_dict["RenderingTool"]))) + menubar.add_cascade(label=lang_dict["ToolMenu"], menu=file_menu) + + #Language menu + language_menu = tk.Menu(menubar, tearoff=0) + language_menu.add_command(label=lang_dict["English"], command=lambda: (changeLanguage(lang_dict["English"]))) + language_menu.add_command(label=lang_dict["Magyar"], command=lambda: (changeLanguage(lang_dict["Magyar"]))) + menubar.add_cascade(label=lang_dict["Language"], menu=language_menu) + + #theme menu + theme_menu = tk.Menu(menubar, tearoff=0) + theme_menu.add_command(label=lang_dict["Dark"], command=lambda: (changeTheme(lang_dict["Dark"]))) + theme_menu.add_command(label=lang_dict["Light"], command=lambda: (changeTheme(lang_dict["Light"]))) + menubar.add_cascade(label=lang_dict["Theme"], menu=theme_menu) + + #Help menu + help_menu = tk.Menu(menubar, tearoff=0) + help_menu.add_command(label=lang_dict["HowMenu"], command=lambda: changeMainPage(lang_dict["HowMenu"])) + help_menu.add_command(label=lang_dict["AboutMenu"], command=lambda: changeMainPage(lang_dict["AboutMenu"])) + menubar.add_cascade(label=lang_dict["HelpMenu"], menu=help_menu) + + #display the menubar + self.config(menu=menubar, bg=BG_COLOR) + + #PAGES + def labelCreate(name): + return tk.Label(self, text=name, **color_font) + + def entryCreate(entry_name): + return tk.Entry(self, name=entry_name, **button_font) + + def fileButtonCreate(button_text,entry): + return tk.Button(self, text=button_text, command=lambda e=entry: selectFile(e), **button_font) + + def folderButtonCreate(button_text,entry): + return tk.Button(self, text=button_text, command=lambda e=entry: selectFolder(e), **button_font) + + #every tool contain Test file/folder, Input file/folder, Expected file/folder, Output labels, textboxes and buttons + def commonGuiElements(): + arg_labels = [lang_dict["TestFile"], lang_dict["InputFile"], lang_dict["ExpectedFile"], lang_dict["OutputFolder"]] + row_index = 1 + + for i, label_text in enumerate(arg_labels): + label = labelCreate(label_text) + label.grid(row=row_index+i, column=0, **gridNSEW) + + entry = entryCreate("entry" + str(i)) + entry.grid(row=row_index+i, column=1, **gridEW) + entries.append(entry) + + if (i < 3): + button = fileButtonCreate(lang_dict["SelectFile"],entry) + button.grid(row=row_index+i, column=2, **gridNSEW) + + folder_button = folderButtonCreate(lang_dict["SelectFolder"],entry) + if (i == 3): + folder_button.grid(row=row_index+i, column=2, **gridNSEW) + else: + folder_button.grid(row=row_index+i, column=3, **gridNSEW) + + #converter tool need Type and Parameters + def converterGuiPlusElements(): + converter_cb_options = [lang_dict["ConvSourceMeter"],lang_dict["ConvPmd"],lang_dict["ConvGitlab"],lang_dict["ConvGitstats"]] + + label = labelCreate(lang_dict["Type"]) + label.grid(row=5, column=0, **gridNSEW) + + self.option_add('*TCombobox*Listbox.background', BTN_COLOR) + self.option_add('*TCombobox*Listbox.foreground', FONT_COLOR) + entry = ttk.Combobox(self, values=converter_cb_options, state='readonly', name="entry4") + + entry.grid(row=5, column=1, **gridEW) + entries_converter.append(entry) + + label = labelCreate(lang_dict["OptParam"]) + label.grid(row=6, column=0, **gridNSEW) + + entry = entryCreate("entry5") + entry.grid(row=6, column=1, **gridEW) + + #put textboxes values to entries_converter array + entries_converter.append(entry) + + #mapping tool need Metrics assign file + def mappingGuiPlusElements(): + label = labelCreate(lang_dict["Metrics"]) + label.grid(row=5, column=0, **gridNSEW) + + entry = entryCreate("entry4") + entry.grid(row=5, column=1, **gridEW) + + entries_mapping.append(entry) + + button = fileButtonCreate(lang_dict["SelectFile"],entry) + button.grid(row=5, column=2, **gridNSEW) + + #about page + def aboutPage(): + label = tk.Label(self, text= program_name + program_version, font=("Helvetica", 20, "bold"), bg=BG_COLOR, fg = FONT_COLOR) + label.grid(row=0, column=2, **gridNSEW) + + label = tk.Label(self, image=logo, **color_font) + label.grid(row=1, column=2) + + label = tk.Label(self, text=ABOUT_TXT, font=def_font, bg=BG_COLOR, fg = FONT_COLOR) + label.grid(row=2, column=2, **gridNSEW) + + #How to? page + def howToPage(): + label = tk.Label(self, text= lang_dict["HowUse"] + program_name, font=("Helvetica", 20), bg=BG_COLOR, fg = FONT_COLOR) + label.grid(row=0, column=2, **gridNSEW) + + label = tk.Label(self, text=HOW_TO_TXT, font=def_font, justify="left", anchor="w", bg=BG_COLOR, fg = FONT_COLOR) + label.grid(row=1, column=2) + + #run button + def runButton(page_name): + run_button = tk.Button(self, text=lang_dict["RunBtn"], command=lambda: (CmdCommand(), lastInputsSave(page_name), changeMainPage(page_name)), **button_font) + run_button.grid(row=7, column=1, **gridNSEW) + + #about page be the default page + aboutPage() + + #Load your last used textbox inputs from a file + #load button + def loadButton(page_name): + if (os.path.isfile(last_textbox_inputs_file_path)): + run_button = tk.Button(self, text=lang_dict["LoadInputs"], command=lambda: (lastInputsLoad(page_name)), **button_font) + run_button.grid(row=7, column=2, **gridNSEW) + + #save textbox content to txt + def lastInputsSave(page_name): + with open(last_textbox_inputs_file_path, 'w') as f: + for i in range (4): + f.write(entries[i].get() + "\n") + + #if tool is converter, save type and optional parameter textbox content + match page_name: + case str(page_name) if lang_dict["ConverterTool"] in page_name: + f.write(entries_converter[0].get() + "\n") + f.write(entries_converter[1].get() + "\n") + case str(page_name) if lang_dict["MappingTool"] in page_name: + f.write(entries_mapping[0].get() + "\n") + + #clear all textbox + entries.clear() + entries_converter.clear() + entries_mapping.clear() + + loadButton(page_name) + + #load txt file lines to textboxes + def lastInputsLoad(page_name): + with open(last_textbox_inputs_file_path, 'r') as f: + lines = f.readlines() + + for i, line in enumerate(lines): + entry_name = "entry" + str(i) + + if entry_name in self.children: + entry = self.nametowidget(entry_name) + entry.delete(0, tk.END) + entry.insert(0, line.strip()) + + if entry_name == "entry4" and page_name == lang_dict["ConverterTool"]: + entry = self.nametowidget(entry_name) + newLine = line.strip() + match newLine: + case str(newLine) if lang_dict["ConvSourceMeter"] in newLine: + entry.current(0) + case str(newLine) if lang_dict["ConvPmd"] in newLine: + entry.current(1) + case str(newLine) if lang_dict["ConvGitlab"] in newLine: + entry.current(2) + case str(newLine) if lang_dict["ConvGitstats"] in newLine: + entry.current(3) + + #row and column alignment + for i in range(5): + self.grid_columnconfigure(i, weight=1) + for i in range(8): + self.grid_rowconfigure(i, weight=1) + + #main page switch function + def switchMenuCommon(page_name,name): + commonGuiElements() + runButton(page_name) + loadButton(page_name) + entries_mapping.clear() + label = tk.Label(self, text=name, bg=BG_COLOR, font=page_font , fg = FONT_COLOR) + label.grid(row=0, column=1, **gridNSEW) + + def changeMainPage(page_name): + for widget in self.grid_slaves(): + widget.grid_forget() + + match page_name: + case str(page_name) if lang_dict["ConverterTool"] in page_name: + switchMenuCommon(page_name,lang_dict["ConverterTool"]) + converterGuiPlusElements() + + case str(page_name) if lang_dict["MappingTool"] in page_name: + switchMenuCommon(page_name,lang_dict["MappingTool"]) + mappingGuiPlusElements() + + case str(page_name) if lang_dict["PlacingTool"] in page_name: + switchMenuCommon(page_name,lang_dict["PlacingTool"]) + + case str(page_name) if lang_dict["RenderingTool"] in page_name: + switchMenuCommon(page_name,lang_dict["RenderingTool"]) + + case str(page_name) if lang_dict["HelpMenu"] in page_name : + aboutPage() + + case str(page_name) if lang_dict["HowMenu"] in page_name : + howToPage() + + case _: + aboutPage() + +if __name__ == "__main__": + app = App() + app.mainloop() diff --git a/sources/test/CodeMetropolis Tester.py b/sources/test/CodeMetropolis Tester.py new file mode 100644 index 00000000..cd1ab00d --- /dev/null +++ b/sources/test/CodeMetropolis Tester.py @@ -0,0 +1,174 @@ +from ast import And +from queue import Empty +import pytest +import subprocess +import os +import shutil +import sys +import argparse +import os.path +from os import path +from os import walk + +#args +parser = argparse.ArgumentParser(description='This is a Python script that uses command line arguments to perform regression tests by comparing expected output files with CodeMetropolis output files.') + +parser.add_argument('test_path', metavar='F', type=str, + help='Specifies the path of one or multiple test files. Required argument!') +parser.add_argument('input_path', metavar='I', type=str, + help='Specifies the path of the input files used for testing. Required argument!') +parser.add_argument('expected_output_path', metavar='E', type=str, + help='Specifies the path of the expected output files. Required argument!') +parser.add_argument('generated_output_path', metavar='O', type=str, + help='Specifies the path of the generated output files by tools. Required argument!') +parser.add_argument('--mapping_file_path', dest='mapping_file_path', type=str, + help='Specifies the path of the mapping file. Required argument, if you test mapping tool output!') +parser.add_argument('--type', dest='types', type=str, + help='Specifies the type for tool. Required argument, if you test converter or rendering tool output!') +parser.add_argument('--parameters', dest='parameters', type=str, + help='Optional parameters. You can use it if supported by the tool') + +#arguments and variables +arguments = parser.parse_args() +test_file_path = arguments.test_path +test_file = None +modified_test_file_path = None +input_path = arguments.input_path +expected_output_path = arguments.expected_output_path +output_path = arguments.generated_output_path +mapping_path = arguments.mapping_file_path +types = arguments.types +parameters = arguments.parameters + +splitted_test_file_path = test_file_path.split('/') +splitted_test_file_backslash = test_file_path.split('\\') + +if '.py' in str(splitted_test_file_path[len(splitted_test_file_path)-1]) and len(splitted_test_file_path)!=1: + test_file = splitted_test_file_path[len(splitted_test_file_path)-1] + modified_test_file_path = test_file_path + test_file_path = "" + for i in range(len(splitted_test_file_path)-1): + test_file_path = test_file_path + splitted_test_file_path[i] + '/' + +if '.py' in str(splitted_test_file_backslash[len(splitted_test_file_backslash)-1]) and len(splitted_test_file_backslash)!=1: + test_file = splitted_test_file_backslash[len(splitted_test_file_backslash)-1] + modified_test_file_path = test_file_path + + test_file_path = "" + for i in range(len(splitted_test_file_backslash)-1): + test_file_path = test_file_path + splitted_test_file_backslash[i] + '\\' + + +#warning functions +def warning(test_file_path, test_file, input_path, expected_output_path, output_path, selected_tool): + error_messages = { + "Invalid test file path!": not path.exists(test_file_path), + "Invalid test file!": str(test_file) != "None" and not path.exists(modified_test_file_path), + "Invalid input file path!": not path.exists(input_path), + "Invalid expected output file path!": not path.exists(expected_output_path), + "Test file directory is empty!": len(os.listdir(test_file_path)) == 0, + "No test on the selected folder!": ".py" not in str(next(walk(test_file_path), (None, None, []))[2]), + "Invalid output path!": output_path is not None and not path.exists(output_path), + "Converter tool requires type argument!": types is None and "converter" in selected_tool, + "Mapping tool requires mapping_file_path argument!": mapping_path is None and "mapping" in selected_tool + } + + for error, condition in error_messages.items(): + if condition: + print(f"Error: {error}") + return -1 + + return 0 + +#._splitter function +def splitter(fileNames): + fileNamesSplit = fileNames.split('.') + fileName = fileNamesSplit[0] + return fileName + +#import pytest file function +def randomTestFileSelect(test_file_path): + sys.path.append(os.path.join(os.path.dirname(__file__), test_file_path)) + fileNames = next(walk(test_file_path), (None, None, []))[2] + fileName = splitter(fileNames[0]) + return fileName + +#run pytest function +def runPytest(test_file, test_file_path, modified_test_file_path, expected_output_path, output_path): + if (test_file == None): + pytest.main([test_file_path, '--expected', expected_output_path, '--output', output_path, "-s"]) + + if (test_file != None): + pytest.main([modified_test_file_path, '--expected', expected_output_path, '--output', output_path, "-s"]) + +#jars functions +#converter tool +def converterTool(input_path, types, parameters, output_path): + if parameters == "None" or parameters is None: + subprocess.call(['java.exe', '-jar', '../distro/converter-1.4.0.jar', '-t', '' + types , '-s' , '' + input_path]), + else: + subprocess.call(['java.exe', '-jar', '../distro/converter-1.4.0.jar', '-t', '' + types , '-s' , '' + input_path , '-p' , '' + parameters]), + + shutil.move(os.path.join('./', 'converterToMapping.xml'), os.path.join(output_path, 'converterToMapping.xml')) + + runPytest(test_file, test_file_path, modified_test_file_path, expected_output_path, output_path) + +#mapping tool +def mappingTool(input_path, mapping_path, output_path): + subprocess.call(['java.exe', '-jar', '../distro/mapping-1.4.0.jar', '-i', '' + input_path , "-m", '' + mapping_path]) + shutil.move(os.path.join('./', 'mappingToPlacing.xml'), os.path.join(output_path, 'mappingToPlacing.xml')) + + runPytest(test_file, test_file_path, modified_test_file_path, expected_output_path, output_path) + +#placing tool +def placingTool(input_path, output_path): + subprocess.call(['java.exe', '-jar', '../distro/placing-1.4.0.jar', '-i', '' + input_path]) + shutil.move(os.path.join('./', 'placingToRendering.xml'), os.path.join(output_path, 'placingToRendering.xml')) + + runPytest(test_file, test_file_path, modified_test_file_path, expected_output_path, output_path) + +#rendering tool +def renderingTool(input_path, types, output_path): + subprocess.call(['java.exe', '-jar', '../distro/rendering-1.4.0.jar', '-i', '' + input_path, '-world', 'world']) + worldExist = os.path.exists(output_path) + if (worldExist == True): + shutil.rmtree(output_path) + + shutil.move(os.path.join('./', 'world'), os.path.join(output_path, 'world')) + + runPytest(test_file, test_file_path, modified_test_file_path, expected_output_path, output_path) + +#MAIN +while True: + #import test file + if (str(test_file) != "None"): + sys.path.append(os.path.join(os.path.dirname(__file__), test_file_path)) + importPytestFile = __import__(splitter(test_file)) + + if (str(test_file) == "None"): + importPytestFile = __import__(randomTestFileSelect(test_file_path)) + + #selected tool from test + selected_tool = importPytestFile.jar + + #warnings + if (warning(test_file_path, test_file, input_path, expected_output_path, output_path, selected_tool) == -1): + break + + match selected_tool: + case "converter": + converterTool(input_path, types, parameters, output_path) + case "mapping": + mappingTool(input_path, mapping_path, output_path) + case "placing": + placingTool(input_path, output_path) + case "rendering": + renderingTool(input_path, types, output_path) + + break + + + + + + diff --git a/sources/test/__pycache__/conftest.cpython-311-pytest-7.2.1.pyc b/sources/test/__pycache__/conftest.cpython-311-pytest-7.2.1.pyc new file mode 100644 index 00000000..eb18851a Binary files /dev/null and b/sources/test/__pycache__/conftest.cpython-311-pytest-7.2.1.pyc differ diff --git a/sources/test/__pycache__/conftest.cpython-311.pyc b/sources/test/__pycache__/conftest.cpython-311.pyc new file mode 100644 index 00000000..042a9f4b Binary files /dev/null and b/sources/test/__pycache__/conftest.cpython-311.pyc differ diff --git a/sources/test/__pycache__/conftest.cpython-39-pytest-6.2.5.pyc b/sources/test/__pycache__/conftest.cpython-39-pytest-6.2.5.pyc new file mode 100644 index 00000000..7af85336 Binary files /dev/null and b/sources/test/__pycache__/conftest.cpython-39-pytest-6.2.5.pyc differ diff --git a/sources/test/config/config.txt b/sources/test/config/config.txt new file mode 100644 index 00000000..3ab5ff49 --- /dev/null +++ b/sources/test/config/config.txt @@ -0,0 +1,2 @@ +language=eng +theme=dark diff --git a/sources/test/config/english_language_file.txt b/sources/test/config/english_language_file.txt new file mode 100644 index 00000000..a30015ba --- /dev/null +++ b/sources/test/config/english_language_file.txt @@ -0,0 +1,46 @@ +Desc=A visual interface to perform regression tests by comparing expected output files with CodeMetropolis tools output files. +MadeBy=Made by: Zoltan Banyai +MadeYear=2023 +Step1=Step 1 - Choose a tool from "Tool" menu +Step2=Step 2 - Test file or folder - Select a specific test file or a folder which contain multiple test +Step3=Step 3 - Input file or folder - Select an input file or folder which compatible with the selected tool +Step4=Step 4 - Expected file or folder - Select an expected output file or folder which will be compare with the output file generated by the tool +Step5=Step 5 - Output folder - Select a folder where the generated output file by tool will be save +Step6=Step 6 - Type - If the Converter tool is selected, you must specify the input type +Step7=Step 7 - Metrics assign file - If the Mapping tool is selected, you must add an xml file which assigns metrics to the metropolis objects +Step8=Step 8 - Optional parameters - If the selected device supports optional parameters, they can be specified here +Step9=Step 9 - Press Run button to use selected tool and run test files +ToolMenu=Tool +HelpMenu=Help +HowMenu=How to? +AboutMenu=About +TestFile=Test file/folder: +InputFile=Input file/folder: +ExpectedFile=Expected file/folder: +OutputFolder=Output folder: +Type=Type: +OptParam=Optional parameters: +Metrics=Metrics assign file: +RunBtn=Run +SelectFile=Select File +SelectFolder=Select Folder +LoadInputs=Load last used inputs +ConvSourceMeter=SourceMeter +ConvPmd=Pmd +ConvGitlab=Gitlab +ConvGitstats=GitStats +ConverterTool=Converter Tool Page +MappingTool=Mapping Tool Page +PlacingTool=Placing Tool Page +RenderingTool=Rendering Tool Page +Language=Language +Theme=Theme +Dark=Dark +Light=Light +Converter=Converter +Mapping=Mapping +Placing=Placing +Rendering=Rendering +English=English +Magyar=Magyar +HowUse=How to use: \ No newline at end of file diff --git a/sources/test/config/hungarian_language_file.txt b/sources/test/config/hungarian_language_file.txt new file mode 100644 index 00000000..77708813 --- /dev/null +++ b/sources/test/config/hungarian_language_file.txt @@ -0,0 +1,46 @@ +Desc=Vizuális felület a regressziós tesztek elvégzéséhez a várt kimeneti fájlok és a CodeMetropolis eszközök kimeneti fájljainak összehasonlításával. +MadeBy=Készítette: Bányai Zoltán +MadeYear=2023 +Step1=Lépés 1 - Válasszon egy eszközt az 'Eszköz' menüből +Step2=Lépés 2 - Teszt fájl/mappa - Válasszon ki egy adott tesztfájlt vagy egy mappát, amely több tesztet tartalmaz +Step3=Lépés 3 - Bemeneti fájl/mappa - Válasszon ki egy beviteli fájlt vagy mappát, amely kompatibilis a kiválasztott eszközze +Step4=Lépés 4 - Elvárt fájl/mappa - Válasszon ki egy várt kimeneti fájlt vagy mappát, amelyet összehasonlít az eszköz által generált kimeneti fájllal +Step5=Lépés 5 - Kimeneti mappa - Válasszon ki egy mappát, ahová az eszközönként generált kimeneti fájl mentésre kerül +Step6=Lépés 6 - Típus - Ha az 'Converter' eszköz van kiválasztva, meg kell adni a bevitel típusát +Step7=Lépés 7 - Metrika hozzárendelő fájl - Ha a 'Mapping' eszköz van kiválasztva, akkor hozzá kell adnia egy xml fájlt, amely metrikákat rendel a metropolisz objektumokhoz +Step8=Lépés 8 - Opcionális paraméterek - Ha a kiválasztott eszköz támogatja az opcionális paramétereket, itt megadhatók +Step9=Lépés 9 - Nyomja meg az Indítás gombot a kiválasztott eszköz használatához és a tesztfájlok futtatásához +ToolMenu=Eszköz +HelpMenu=Súgó +HowMenu=Hogyan? +AboutMenu=Névjegy +TestFile=Teszt fájl/mappa: +InputFile=Bemeneti fájl/mappa: +ExpectedFile=Elvárt fájl/mappa: +OutputFolder=Kimeneti mappa: +Type=Típus: +OptParam=Opcionális paraméterek: +Metrics=Metrika hozzárendelő fájl: +RunBtn=Indítás +SelectFile=Fájlválasztás +SelectFolder=Mappaválasztás +LoadInputs=Legutóbbi bemenetek betöltése +ConvSourceMeter=SourceMeter +ConvPmd=Pmd +ConvGitlab=Gitlab +ConvGitstats=GitStats +ConverterTool=Converter Eszköz oldala +MappingTool=Mapping Eszköz oldala +PlacingTool=Placing Eszköz oldala +RenderingTool=Rendering Eszköz oldala +Language=Nyelv +Theme=Téma +Dark=Sötét +Light=Világos +Converter=Converter +Mapping=Mapping +Placing=Placing +Rendering=Rendering +English=English +Magyar=Magyar +HowUse=Hogyan használd: \ No newline at end of file diff --git a/sources/test/config/icon.ico b/sources/test/config/icon.ico new file mode 100644 index 00000000..aa06cce6 Binary files /dev/null and b/sources/test/config/icon.ico differ diff --git a/sources/test/config/logo_transparent.png b/sources/test/config/logo_transparent.png new file mode 100644 index 00000000..f115ce2f Binary files /dev/null and b/sources/test/config/logo_transparent.png differ diff --git a/sources/test/config/textbox_last_input.txt b/sources/test/config/textbox_last_input.txt new file mode 100644 index 00000000..fa1e8bcb --- /dev/null +++ b/sources/test/config/textbox_last_input.txt @@ -0,0 +1,6 @@ +C:/Users/Zoli/CodeMetropolis/sources/test/testFiles/converter +C:/Users/Zoli/CodeMetropolis/sources/test/testing/converter/TestProject_Simple1.graph +C:/Users/Zoli/CodeMetropolis/sources/test/testing/converter/expected.xml +C:/Users/Zoli/CodeMetropolis/sources/test/testing/converter +SourceMeter + diff --git a/sources/test/conftest.py b/sources/test/conftest.py new file mode 100644 index 00000000..3962f15f --- /dev/null +++ b/sources/test/conftest.py @@ -0,0 +1,153 @@ +import pytest +from xml.etree import ElementTree as ET + +#constants +ELEMENT = "element" +PROPERTY = "property" +PROPERTIES = "properties" +CHILDREN = "children" +ATTRIBUTES = "attributes" +ATTRIBUTE = "attribute" +BUILDABLE = "buildable" +POSITION = "position" +SIZE = "size" +NAME = "name" +TYPE = "type" +VALUE = "value" +X = "x" +Y = "y" +Z = "z" +FROM = "from" +TO = "to" +VERSION = "version" +NONE = None + +# get arguments +def pytest_addoption(parser): + parser.addoption("--expected") + parser.addoption("--output") + +#fixures to parse xml +@pytest.fixture +def expected_xml(request): + expected = request.config.getoption("--expected") + tree = ET.parse(expected) + return tree + +@pytest.fixture +def converter_output_xml(request): + output = request.config.getoption("--output") + output_full_path = f"{output}/converterToMapping.xml" + tree = ET.parse(output_full_path) + return tree + +@pytest.fixture +def mapping_output_xml(request): + output = request.config.getoption("--output") + output_full_path = f"{output}/mappingToPlacing.xml" + tree = ET.parse(output_full_path) + return tree + +@pytest.fixture +def placing_output_xml(request): + output = request.config.getoption("--output") + output_full_path = f"{output}/placingToRendering.xml" + tree = ET.parse(output_full_path) + return tree + +@pytest.fixture +def rendering_output_path(request): + output = request.config.getoption("--output") + output_full_path = f"{output}/world" + return output_full_path + +@pytest.fixture +def expected_rendering_path(request): + expected_rendering = request.config.getoption("--expected") + return expected_rendering + + +#functions for testing +def count_tags(xml, tag): + root = xml.getroot() + return len(list(root.iter(tag))) + +def root_tag(xml, attribute): + root = xml.getroot() + return root.attrib.get(attribute) + +def extract_tags_and_attributes_nested(tree, parent_path_elem, parent_elem, selected_elem, selected_attr): + root = tree.getroot() + + #parent map + parent_map = {child: parent for parent in tree.iter() for child in parent} + diction = {} + + for elem in root.iter(): + if elem.tag == parent_path_elem: + name = elem.attrib.get(NAME) + if name == "": + name = None + #tupple + parents = () + parent = parent_map.get(elem) + while parent is not None: + parent_name = parent.attrib.get(NAME) + if parent_name: + parents = (parent_name,) + parents + parent = parent_map.get(parent, None) + #key set + parents = parents + (name,) + + if parent_elem != None: + properties = elem.find(parent_elem) + if properties != None: + sub_tags = properties.findall(selected_elem) + sub_names = [tag.attrib.get(selected_attr) for tag in sub_tags] + + else: + sub_tags = elem.find(selected_elem) + sub_names = [sub_tags.attrib.get(selected_attr)] + + sub_names.sort() + + if parents in diction: + diction[parents].append(tuple(sub_names)) + else: + diction[parents] = [tuple(sub_names)] + + return diction + + +def extract_tags_and_attributes(tree, parent_path_elem, selected_attr): + root = tree.getroot() + + + parent_map = {child: parent for parent in tree.iter() for child in parent} + diction = {} + + for elem in root.iter(): + if elem.tag == parent_path_elem: + name = elem.attrib.get(NAME) + if name == "": + name = None + parents = () + parent = parent_map.get(elem) + while parent is not None: + parent_name = parent.attrib.get(NAME) + if parent_name: + parents = (parent_name,) + parents + parent = parent_map.get(parent, None) + parents = parents + (name,) + + sel_act = elem.attrib.get(selected_attr) + + if parents in diction: + diction[parents].append((sel_act,)) + else: + diction[parents] = [(sel_act,)] + + return diction + + + diff --git a/sources/test/testFiles/__pycache__/elementNameMatch_test.cpython-39.pyc b/sources/test/testFiles/__pycache__/elementNameMatch_test.cpython-39.pyc new file mode 100644 index 00000000..286db87e Binary files /dev/null and b/sources/test/testFiles/__pycache__/elementNameMatch_test.cpython-39.pyc differ diff --git a/sources/test/testFiles/__pycache__/numberOfClasses_test.cpython-39.pyc b/sources/test/testFiles/__pycache__/numberOfClasses_test.cpython-39.pyc new file mode 100644 index 00000000..f723180f Binary files /dev/null and b/sources/test/testFiles/__pycache__/numberOfClasses_test.cpython-39.pyc differ diff --git a/sources/test/testFiles/converter/__pycache__/test_children_tags_count.cpython-311.pyc b/sources/test/testFiles/converter/__pycache__/test_children_tags_count.cpython-311.pyc new file mode 100644 index 00000000..e7da6cf5 Binary files /dev/null and b/sources/test/testFiles/converter/__pycache__/test_children_tags_count.cpython-311.pyc differ diff --git a/sources/test/testFiles/converter/__pycache__/test_element_tags_count.cpython-311-pytest-7.2.1.pyc b/sources/test/testFiles/converter/__pycache__/test_element_tags_count.cpython-311-pytest-7.2.1.pyc new file mode 100644 index 00000000..31a891d0 Binary files /dev/null and b/sources/test/testFiles/converter/__pycache__/test_element_tags_count.cpython-311-pytest-7.2.1.pyc differ diff --git a/sources/test/testFiles/converter/__pycache__/test_element_tags_name_attributes_match.cpython-311-pytest-7.2.1.pyc b/sources/test/testFiles/converter/__pycache__/test_element_tags_name_attributes_match.cpython-311-pytest-7.2.1.pyc new file mode 100644 index 00000000..b9d8fe30 Binary files /dev/null and b/sources/test/testFiles/converter/__pycache__/test_element_tags_name_attributes_match.cpython-311-pytest-7.2.1.pyc differ diff --git a/sources/test/testFiles/converter/__pycache__/test_element_tags_type_attributes_match.cpython-311-pytest-7.2.1.pyc b/sources/test/testFiles/converter/__pycache__/test_element_tags_type_attributes_match.cpython-311-pytest-7.2.1.pyc new file mode 100644 index 00000000..7977119e Binary files /dev/null and b/sources/test/testFiles/converter/__pycache__/test_element_tags_type_attributes_match.cpython-311-pytest-7.2.1.pyc differ diff --git a/sources/test/testFiles/converter/__pycache__/test_properties_tags_count.cpython-311-pytest-7.2.1.pyc b/sources/test/testFiles/converter/__pycache__/test_properties_tags_count.cpython-311-pytest-7.2.1.pyc new file mode 100644 index 00000000..c510077b Binary files /dev/null and b/sources/test/testFiles/converter/__pycache__/test_properties_tags_count.cpython-311-pytest-7.2.1.pyc differ diff --git a/sources/test/testFiles/converter/__pycache__/test_property_tag_count.cpython-311-pytest-7.2.1.pyc b/sources/test/testFiles/converter/__pycache__/test_property_tag_count.cpython-311-pytest-7.2.1.pyc new file mode 100644 index 00000000..cc523343 Binary files /dev/null and b/sources/test/testFiles/converter/__pycache__/test_property_tag_count.cpython-311-pytest-7.2.1.pyc differ diff --git a/sources/test/testFiles/converter/__pycache__/test_property_tags_name_attributes_match.cpython-311-pytest-7.2.1.pyc b/sources/test/testFiles/converter/__pycache__/test_property_tags_name_attributes_match.cpython-311-pytest-7.2.1.pyc new file mode 100644 index 00000000..38828041 Binary files /dev/null and b/sources/test/testFiles/converter/__pycache__/test_property_tags_name_attributes_match.cpython-311-pytest-7.2.1.pyc differ diff --git a/sources/test/testFiles/converter/__pycache__/test_property_tags_type_attributes_match.cpython-311-pytest-7.2.1.pyc b/sources/test/testFiles/converter/__pycache__/test_property_tags_type_attributes_match.cpython-311-pytest-7.2.1.pyc new file mode 100644 index 00000000..fb093803 Binary files /dev/null and b/sources/test/testFiles/converter/__pycache__/test_property_tags_type_attributes_match.cpython-311-pytest-7.2.1.pyc differ diff --git a/sources/test/testFiles/converter/__pycache__/test_root_element_name_attribute_match.cpython-311-pytest-7.2.1.pyc b/sources/test/testFiles/converter/__pycache__/test_root_element_name_attribute_match.cpython-311-pytest-7.2.1.pyc new file mode 100644 index 00000000..8b9017d5 Binary files /dev/null and b/sources/test/testFiles/converter/__pycache__/test_root_element_name_attribute_match.cpython-311-pytest-7.2.1.pyc differ diff --git a/sources/test/testFiles/converter/__pycache__/test_root_element_type_attribute_match.cpython-311-pytest-7.2.1.pyc b/sources/test/testFiles/converter/__pycache__/test_root_element_type_attribute_match.cpython-311-pytest-7.2.1.pyc new file mode 100644 index 00000000..c685acee Binary files /dev/null and b/sources/test/testFiles/converter/__pycache__/test_root_element_type_attribute_match.cpython-311-pytest-7.2.1.pyc differ diff --git a/sources/test/testFiles/converter/test_children_tags_count.py b/sources/test/testFiles/converter/test_children_tags_count.py new file mode 100644 index 00000000..21efaa4d --- /dev/null +++ b/sources/test/testFiles/converter/test_children_tags_count.py @@ -0,0 +1,11 @@ +from conftest import count_tags +from conftest import CHILDREN + +jar = 'converter' + +def test_children_tags_count(expected_xml, converter_output_xml): + + expected_count = count_tags(expected_xml, CHILDREN) + output_count = count_tags(converter_output_xml, CHILDREN) + + assert expected_count == output_count, f"test_children_tags_count: The number of 'children' tags does not match. Expected {expected_count}, but got {output_count} tags." diff --git a/sources/test/testFiles/converter/test_element_tags_count.py b/sources/test/testFiles/converter/test_element_tags_count.py new file mode 100644 index 00000000..bcc2c4ad --- /dev/null +++ b/sources/test/testFiles/converter/test_element_tags_count.py @@ -0,0 +1,11 @@ +from conftest import count_tags +from conftest import ELEMENT + +jar = 'converter' + +def test_element_tags_count(expected_xml, converter_output_xml): + + expected_count = count_tags(expected_xml, ELEMENT) + output_count = count_tags(converter_output_xml, ELEMENT) + + assert expected_count == output_count, f"test_element_tags_count: The number of 'element' tags does not match. Expected {expected_count}, but got {output_count} tags." diff --git a/sources/test/testFiles/converter/test_element_tags_name_attributes_match.py b/sources/test/testFiles/converter/test_element_tags_name_attributes_match.py new file mode 100644 index 00000000..818e0e9a --- /dev/null +++ b/sources/test/testFiles/converter/test_element_tags_name_attributes_match.py @@ -0,0 +1,12 @@ +from conftest import extract_tags_and_attributes +from conftest import ELEMENT +from conftest import NAME + +jar = 'converter' + +def test_element_tags_name_attributes_match(expected_xml, converter_output_xml): + result_expected = extract_tags_and_attributes(expected_xml, ELEMENT, NAME) + result_output = extract_tags_and_attributes(converter_output_xml, ELEMENT, NAME) + + # Szülő_útvonal_ell + assert set(result_expected.keys()) == set(result_output.keys()), f"test_element_tags_name_attributes_match: The parent map is different between the expected and generated output" diff --git a/sources/test/testFiles/converter/test_element_tags_type_attributes_match.py b/sources/test/testFiles/converter/test_element_tags_type_attributes_match.py new file mode 100644 index 00000000..f59026a0 --- /dev/null +++ b/sources/test/testFiles/converter/test_element_tags_type_attributes_match.py @@ -0,0 +1,14 @@ +from conftest import extract_tags_and_attributes +from conftest import ELEMENT +from conftest import TYPE + +jar = 'converter' + +def test_element_tags_type_attributes_match(expected_xml, converter_output_xml): + result_expected = extract_tags_and_attributes(expected_xml, ELEMENT, TYPE) + result_output = extract_tags_and_attributes(converter_output_xml, ELEMENT, TYPE) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_element_tags_type_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_element_tags_type_attributes_match: Different 'element' type attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/converter/test_properties_tags_count.py b/sources/test/testFiles/converter/test_properties_tags_count.py new file mode 100644 index 00000000..84ff8ef0 --- /dev/null +++ b/sources/test/testFiles/converter/test_properties_tags_count.py @@ -0,0 +1,11 @@ +from conftest import count_tags +from conftest import PROPERTIES + +jar = 'converter' + +def test_properties_tags_count(expected_xml, converter_output_xml): + + expected_count = count_tags(expected_xml, PROPERTIES) + output_count = count_tags(converter_output_xml, PROPERTIES) + + assert expected_count == output_count, f"test_properties_tags_count: The number of 'properties' tags does not match. Expected {expected_count}, but got {output_count} tags." diff --git a/sources/test/testFiles/converter/test_property_tag_count.py b/sources/test/testFiles/converter/test_property_tag_count.py new file mode 100644 index 00000000..42228fba --- /dev/null +++ b/sources/test/testFiles/converter/test_property_tag_count.py @@ -0,0 +1,11 @@ +from conftest import count_tags +from conftest import PROPERTY + +jar = 'converter' + +def test_property_tags_count(expected_xml, converter_output_xml): + + expected_count = count_tags(expected_xml, PROPERTY) + output_count = count_tags(converter_output_xml, PROPERTY) + + assert expected_count == output_count, f"test_property_tags_count: The number of 'property' tags does not match. Expected {expected_count}, but got {output_count} tags." diff --git a/sources/test/testFiles/converter/test_property_tags_name_attributes_match.py b/sources/test/testFiles/converter/test_property_tags_name_attributes_match.py new file mode 100644 index 00000000..df18115a --- /dev/null +++ b/sources/test/testFiles/converter/test_property_tags_name_attributes_match.py @@ -0,0 +1,18 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import ELEMENT +from conftest import PROPERTIES +from conftest import PROPERTY +from conftest import NAME + +jar = 'converter' + +def test_property_tags_name_attributes_match(expected_xml, converter_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, ELEMENT, PROPERTIES, PROPERTY, NAME) + result_output = extract_tags_and_attributes_nested(converter_output_xml, ELEMENT, PROPERTIES, PROPERTY, NAME) + + # Szülő_útvonal_ell + assert set(result_expected.keys()) == set(result_output.keys()), "test_property_tags_name_attributes_match: The parent map is different between the expected and generated output" + + #Értékek_ell + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_property_tags_name_attributes_match: Different 'property' name attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/converter/test_property_tags_type_attributes_match.py b/sources/test/testFiles/converter/test_property_tags_type_attributes_match.py new file mode 100644 index 00000000..fe5edce2 --- /dev/null +++ b/sources/test/testFiles/converter/test_property_tags_type_attributes_match.py @@ -0,0 +1,19 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import ELEMENT +from conftest import PROPERTIES +from conftest import PROPERTY +from conftest import TYPE + +jar = 'converter' + +def test_property_tags_type_attributes_match(expected_xml, converter_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, ELEMENT, PROPERTIES, PROPERTY, TYPE) + result_output = extract_tags_and_attributes_nested(converter_output_xml, ELEMENT, PROPERTIES, PROPERTY, TYPE) + + # Szülő_útvonal_ell + assert set(result_expected.keys()) == set(result_output.keys()), "test_property_tags_type_attributes_match: The parent map is different between the expected and generated output" + + #Értékek_ell + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_property_tags_type_attributes_match: Different 'property' type attribute value. Path to the different value:\n {key} " + diff --git a/sources/test/testFiles/converter/test_root_element_name_attribute_match.py b/sources/test/testFiles/converter/test_root_element_name_attribute_match.py new file mode 100644 index 00000000..7e340ae1 --- /dev/null +++ b/sources/test/testFiles/converter/test_root_element_name_attribute_match.py @@ -0,0 +1,11 @@ +from conftest import root_tag +from conftest import NAME + +jar = 'converter' + +def test_root_element_name_attribute_match(expected_xml, converter_output_xml): + + expected_root_name = root_tag(expected_xml, NAME) + output_root_name = root_tag(converter_output_xml, NAME) + + assert expected_root_name == output_root_name, f"test_root_element_name_attribute_match: The 'name' attribute of the root element does not match. Expected '{expected_root_name}' attribute value, but got '{output_root_name}'" diff --git a/sources/test/testFiles/converter/test_root_element_type_attribute_match.py b/sources/test/testFiles/converter/test_root_element_type_attribute_match.py new file mode 100644 index 00000000..fcca9550 --- /dev/null +++ b/sources/test/testFiles/converter/test_root_element_type_attribute_match.py @@ -0,0 +1,11 @@ +from conftest import root_tag +from conftest import TYPE + +jar = 'converter' + +def test_root_element_type_attribute_match(expected_xml, converter_output_xml): + + expected_root_type = root_tag(expected_xml, TYPE) + output_root_type = root_tag(converter_output_xml, TYPE) + + assert expected_root_type == output_root_type, f"test_root_element_type_attribute_match: The 'type' attribute of the root element does not match. Expected '{expected_root_type}' attribute value, but got '{output_root_type}'" diff --git a/sources/test/testFiles/mapping/test_attribute_tag_count.py b/sources/test/testFiles/mapping/test_attribute_tag_count.py new file mode 100644 index 00000000..b3587e4c --- /dev/null +++ b/sources/test/testFiles/mapping/test_attribute_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import ATTRIBUTE + +jar = 'mapping' + +def test_attribute_tags_count(expected_xml, mapping_output_xml): + + expected_count = count_tags(expected_xml, ATTRIBUTE) + output_count = count_tags(mapping_output_xml, ATTRIBUTE) + + assert expected_count == output_count, f"test_attribute_tags_count: The number of 'attribute' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/mapping/test_attribute_tags_name_attributes_match.py b/sources/test/testFiles/mapping/test_attribute_tags_name_attributes_match.py new file mode 100644 index 00000000..b8d2af9d --- /dev/null +++ b/sources/test/testFiles/mapping/test_attribute_tags_name_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import ATTRIBUTES +from conftest import ATTRIBUTE +from conftest import NAME + +jar = 'mapping' + +def test_attribute_tags_name_attributes_match(expected_xml, mapping_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, ATTRIBUTES, ATTRIBUTE, NAME) + result_output = extract_tags_and_attributes_nested(mapping_output_xml, BUILDABLE, ATTRIBUTES, ATTRIBUTE, NAME) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_attribute_tags_name_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_attribute_tags_name_attributes_match: Different 'attribute' name attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/mapping/test_attribute_tags_value_attributes_match.py b/sources/test/testFiles/mapping/test_attribute_tags_value_attributes_match.py new file mode 100644 index 00000000..e045244f --- /dev/null +++ b/sources/test/testFiles/mapping/test_attribute_tags_value_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import ATTRIBUTES +from conftest import ATTRIBUTE +from conftest import VALUE + +jar = 'mapping' + +def test_attribute_tags_value_attributes_match(expected_xml, mapping_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, ATTRIBUTES, ATTRIBUTE, VALUE) + result_output = extract_tags_and_attributes_nested(mapping_output_xml, BUILDABLE, ATTRIBUTES, ATTRIBUTE, VALUE) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_attribute_tags_value_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_attribute_tags_value_attributes_match: Different 'attribute' value attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/mapping/test_attributes_tag_count.py b/sources/test/testFiles/mapping/test_attributes_tag_count.py new file mode 100644 index 00000000..57c140e0 --- /dev/null +++ b/sources/test/testFiles/mapping/test_attributes_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import ATTRIBUTES + +jar = 'mapping' + +def test_attributes_tags_count(expected_xml, mapping_output_xml): + + expected_count = count_tags(expected_xml, ATTRIBUTES) + output_count = count_tags(mapping_output_xml, ATTRIBUTES) + + assert expected_count == output_count, f"test_attributes_tags_count: The number of 'attributes' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/mapping/test_buildable_tag_count.py b/sources/test/testFiles/mapping/test_buildable_tag_count.py new file mode 100644 index 00000000..4165cccb --- /dev/null +++ b/sources/test/testFiles/mapping/test_buildable_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import BUILDABLE + +jar = 'mapping' + +def test_buildable_tags_count(expected_xml, mapping_output_xml): + + expected_count = count_tags(expected_xml, BUILDABLE) + output_count = count_tags(mapping_output_xml, BUILDABLE) + + assert expected_count == output_count, f"test_buildable_tags_count: The number of 'buildable' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/mapping/test_buildable_tags_name_attributes_match.py b/sources/test/testFiles/mapping/test_buildable_tags_name_attributes_match.py new file mode 100644 index 00000000..cfc8bb97 --- /dev/null +++ b/sources/test/testFiles/mapping/test_buildable_tags_name_attributes_match.py @@ -0,0 +1,12 @@ +from conftest import extract_tags_and_attributes +from conftest import BUILDABLE +from conftest import NAME + +jar = 'mapping' + +def test_buildable_tags_name_attributes_match(expected_xml, mapping_output_xml): + result_expected = extract_tags_and_attributes(expected_xml, BUILDABLE, NAME) + result_output = extract_tags_and_attributes(mapping_output_xml, BUILDABLE, NAME) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_buildable_tags_name_attributes_match: The parent map is different between the expected and generated output" + diff --git a/sources/test/testFiles/mapping/test_buildable_tags_type_attributes_match.py b/sources/test/testFiles/mapping/test_buildable_tags_type_attributes_match.py new file mode 100644 index 00000000..d8b27a31 --- /dev/null +++ b/sources/test/testFiles/mapping/test_buildable_tags_type_attributes_match.py @@ -0,0 +1,14 @@ +from conftest import extract_tags_and_attributes +from conftest import BUILDABLE +from conftest import TYPE + +jar = 'mapping' + +def test_buildable_tags_type_attributes_match(expected_xml, mapping_output_xml): + result_expected = extract_tags_and_attributes(expected_xml, BUILDABLE, TYPE) + result_output = extract_tags_and_attributes(mapping_output_xml, BUILDABLE, TYPE) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_buildable_tags_type_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_buildable_tags_type_attributes_match: Different 'element' type attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/mapping/test_children_tag_count.py b/sources/test/testFiles/mapping/test_children_tag_count.py new file mode 100644 index 00000000..713ff017 --- /dev/null +++ b/sources/test/testFiles/mapping/test_children_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import CHILDREN + +jar = 'mapping' + +def test_children_tags_count(expected_xml, mapping_output_xml): + + expected_count = count_tags(expected_xml, CHILDREN) + output_count = count_tags(mapping_output_xml, CHILDREN) + + assert expected_count == output_count, f"test_children_tags_count: The number of 'children' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/mapping/test_position_tag_count.py b/sources/test/testFiles/mapping/test_position_tag_count.py new file mode 100644 index 00000000..0be14a6d --- /dev/null +++ b/sources/test/testFiles/mapping/test_position_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import POSITION + +jar = 'mapping' + +def test_position_tags_count(expected_xml, mapping_output_xml): + + expected_count = count_tags(expected_xml, POSITION) + output_count = count_tags(mapping_output_xml, POSITION) + + assert expected_count == output_count, f"test_position_tags_count: The number of 'position' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/mapping/test_position_tags_x_attributes_match.py b/sources/test/testFiles/mapping/test_position_tags_x_attributes_match.py new file mode 100644 index 00000000..9a2aa0b6 --- /dev/null +++ b/sources/test/testFiles/mapping/test_position_tags_x_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import POSITION +from conftest import X + +jar = 'mapping' + +def test_position_tags_x_attributes_match(expected_xml, mapping_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, POSITION, X) + result_output = extract_tags_and_attributes_nested(mapping_output_xml, BUILDABLE, NONE, POSITION, X) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_position_tags_x_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_position_tags_x_attributes_match: Different 'position' x attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/mapping/test_position_tags_y_attributes_match.py b/sources/test/testFiles/mapping/test_position_tags_y_attributes_match.py new file mode 100644 index 00000000..8c52d119 --- /dev/null +++ b/sources/test/testFiles/mapping/test_position_tags_y_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import POSITION +from conftest import Y + +jar = 'mapping' + +def test_position_tags_y_attributes_match(expected_xml, mapping_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, POSITION, Y) + result_output = extract_tags_and_attributes_nested(mapping_output_xml, BUILDABLE, NONE, POSITION, Y) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_position_tags_y_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_position_tags_y_attributes_match: Different 'position' y attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/mapping/test_position_tags_z_attributes_match.py b/sources/test/testFiles/mapping/test_position_tags_z_attributes_match.py new file mode 100644 index 00000000..d031494f --- /dev/null +++ b/sources/test/testFiles/mapping/test_position_tags_z_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import POSITION +from conftest import Z + +jar = 'mapping' + +def test_position_tags_z_attributes_match(expected_xml, mapping_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, POSITION, Z) + result_output = extract_tags_and_attributes_nested(mapping_output_xml, BUILDABLE, NONE, POSITION, Z) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_position_tags_z_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_position_tags_z_attributes_match: Different 'position' z attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/mapping/test_root_element_from_attribute_match.py b/sources/test/testFiles/mapping/test_root_element_from_attribute_match.py new file mode 100644 index 00000000..0d550103 --- /dev/null +++ b/sources/test/testFiles/mapping/test_root_element_from_attribute_match.py @@ -0,0 +1,11 @@ +from conftest import root_tag +from conftest import FROM + +jar = 'mapping' + +def test_root_element_from_attribute_match(expected_xml, mapping_output_xml): + + expected_root_from = root_tag(expected_xml, FROM) + output_root_from = root_tag(mapping_output_xml, FROM) + + assert expected_root_from == output_root_from, f"test_root_element_from_attribute_match: The 'from' attribute of the root element does not match. Expected '{expected_root_from}' attribute value, but got '{output_root_from}'" diff --git a/sources/test/testFiles/mapping/test_root_element_to_attribute_match.py b/sources/test/testFiles/mapping/test_root_element_to_attribute_match.py new file mode 100644 index 00000000..ea6c0f40 --- /dev/null +++ b/sources/test/testFiles/mapping/test_root_element_to_attribute_match.py @@ -0,0 +1,11 @@ +from conftest import root_tag +from conftest import TO + +jar = 'mapping' + +def test_root_element_to_attribute_match(expected_xml, mapping_output_xml): + + expected_root_to = root_tag(expected_xml, TO) + output_root_to = root_tag(mapping_output_xml, TO) + + assert expected_root_to == output_root_to, f"test_root_element_to_attribute_match: The 'to' attribute of the root element does not match. Expected '{expected_root_to}' attribute value, but got '{output_root_to}'" diff --git a/sources/test/testFiles/mapping/test_root_element_version_attribute_match.py b/sources/test/testFiles/mapping/test_root_element_version_attribute_match.py new file mode 100644 index 00000000..efd6969e --- /dev/null +++ b/sources/test/testFiles/mapping/test_root_element_version_attribute_match.py @@ -0,0 +1,11 @@ +from conftest import root_tag +from conftest import VERSION + +jar = 'mapping' + +def test_root_element_version_attribute_match(expected_xml, mapping_output_xml): + + expected_root_version = root_tag(expected_xml, VERSION) + output_root_version = root_tag(mapping_output_xml, VERSION) + + assert expected_root_version == output_root_version, f"test_root_element_version_attribute_match: The 'version' attribute of the root element does not match. Expected '{expected_root_version}' attribute value, but got '{output_root_version}'" diff --git a/sources/test/testFiles/mapping/test_size_tag_count.py b/sources/test/testFiles/mapping/test_size_tag_count.py new file mode 100644 index 00000000..bca1e70c --- /dev/null +++ b/sources/test/testFiles/mapping/test_size_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import SIZE + +jar = 'mapping' + +def test_size_tags_count(expected_xml, mapping_output_xml): + + expected_count = count_tags(expected_xml, SIZE) + output_count = count_tags(mapping_output_xml, SIZE) + + assert expected_count == output_count, f"test_size_tags_count: The number of 'size' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/mapping/test_size_tags_x_attributes_match.py b/sources/test/testFiles/mapping/test_size_tags_x_attributes_match.py new file mode 100644 index 00000000..1a1382e3 --- /dev/null +++ b/sources/test/testFiles/mapping/test_size_tags_x_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import SIZE +from conftest import X + +jar = 'mapping' + +def test_size_tags_x_attributes_match(expected_xml, mapping_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, SIZE, X) + result_output = extract_tags_and_attributes_nested(mapping_output_xml, BUILDABLE, NONE, SIZE, X) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_size_tags_x_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_size_tags_x_attributes_match: Different 'size' x attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/mapping/test_size_tags_y_attributes_match.py b/sources/test/testFiles/mapping/test_size_tags_y_attributes_match.py new file mode 100644 index 00000000..691d1baf --- /dev/null +++ b/sources/test/testFiles/mapping/test_size_tags_y_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import SIZE +from conftest import Y + +jar = 'mapping' + +def test_size_tags_y_attributes_match(expected_xml, mapping_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, SIZE, Y) + result_output = extract_tags_and_attributes_nested(mapping_output_xml, BUILDABLE, NONE, SIZE, Y) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_size_tags_y_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_size_tags_y_attributes_match: Different 'size' y attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/mapping/test_size_tags_z_attributes_match.py b/sources/test/testFiles/mapping/test_size_tags_z_attributes_match.py new file mode 100644 index 00000000..afcc4835 --- /dev/null +++ b/sources/test/testFiles/mapping/test_size_tags_z_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import SIZE +from conftest import Z + +jar = 'mapping' + +def test_size_tags_z_attributes_match(expected_xml, mapping_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, SIZE, Z) + result_output = extract_tags_and_attributes_nested(mapping_output_xml, BUILDABLE, NONE, SIZE, Z) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_size_tags_z_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_size_tags_z_attributes_match: Different 'size' z attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/placing/test_attribute_tag_count.py b/sources/test/testFiles/placing/test_attribute_tag_count.py new file mode 100644 index 00000000..8738de72 --- /dev/null +++ b/sources/test/testFiles/placing/test_attribute_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import ATTRIBUTE + +jar = 'placing' + +def test_attribute_tags_count(expected_xml, placing_output_xml): + + expected_count = count_tags(expected_xml, ATTRIBUTE) + output_count = count_tags(placing_output_xml, ATTRIBUTE) + + assert expected_count == output_count, f"test_attribute_tags_count: The number of 'attribute' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/placing/test_attribute_tags_name_attributes_match.py b/sources/test/testFiles/placing/test_attribute_tags_name_attributes_match.py new file mode 100644 index 00000000..a7edda2c --- /dev/null +++ b/sources/test/testFiles/placing/test_attribute_tags_name_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import ATTRIBUTES +from conftest import ATTRIBUTE +from conftest import NAME + +jar = 'placing' + +def test_attribute_tags_name_attributes_match(expected_xml, placing_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, ATTRIBUTES, ATTRIBUTE, NAME) + result_output = extract_tags_and_attributes_nested(placing_output_xml, BUILDABLE, ATTRIBUTES, ATTRIBUTE, NAME) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_attribute_tags_name_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_attribute_tags_name_attributes_match: Different 'attribute' name attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/placing/test_attribute_tags_value_attributes_match.py b/sources/test/testFiles/placing/test_attribute_tags_value_attributes_match.py new file mode 100644 index 00000000..6ba1abef --- /dev/null +++ b/sources/test/testFiles/placing/test_attribute_tags_value_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import ATTRIBUTES +from conftest import ATTRIBUTE +from conftest import VALUE + +jar = 'placing' + +def test_attribute_tags_value_attributes_match(expected_xml, placing_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, ATTRIBUTES, ATTRIBUTE, VALUE) + result_output = extract_tags_and_attributes_nested(placing_output_xml, BUILDABLE, ATTRIBUTES, ATTRIBUTE, VALUE) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_attribute_tags_value_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_attribute_tags_value_attributes_match: Different 'attribute' value attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/placing/test_attributes_tag_count.py b/sources/test/testFiles/placing/test_attributes_tag_count.py new file mode 100644 index 00000000..9dc9adfb --- /dev/null +++ b/sources/test/testFiles/placing/test_attributes_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import ATTRIBUTES + +jar = 'placing' + +def test_attributes_tags_count(expected_xml, placing_output_xml): + + expected_count = count_tags(expected_xml, ATTRIBUTES) + output_count = count_tags(placing_output_xml, ATTRIBUTES) + + assert expected_count == output_count, f"test_attributes_tags_count: The number of 'attributes' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/placing/test_buildable_tag_count.py b/sources/test/testFiles/placing/test_buildable_tag_count.py new file mode 100644 index 00000000..e6f8007e --- /dev/null +++ b/sources/test/testFiles/placing/test_buildable_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import BUILDABLE + +jar = 'placing' + +def test_buildable_tags_count(expected_xml, placing_output_xml): + + expected_count = count_tags(expected_xml, BUILDABLE) + output_count = count_tags(placing_output_xml, BUILDABLE) + + assert expected_count == output_count, f"test_buildable_tags_count: The number of 'buildable' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/placing/test_buildable_tags_name_attributes_match.py b/sources/test/testFiles/placing/test_buildable_tags_name_attributes_match.py new file mode 100644 index 00000000..34fc1ace --- /dev/null +++ b/sources/test/testFiles/placing/test_buildable_tags_name_attributes_match.py @@ -0,0 +1,11 @@ +from conftest import extract_tags_and_attributes +from conftest import BUILDABLE +from conftest import NAME + +jar = 'placing' + +def test_buildable_tags_name_attributes_match(expected_xml, placing_output_xml): + result_expected = extract_tags_and_attributes(expected_xml, BUILDABLE, NAME) + result_output = extract_tags_and_attributes(placing_output_xml, BUILDABLE, NAME) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_buildable_tags_name_attributes_match: The parent map is different between the expected and generated output" diff --git a/sources/test/testFiles/placing/test_buildable_tags_type_attributes_match.py b/sources/test/testFiles/placing/test_buildable_tags_type_attributes_match.py new file mode 100644 index 00000000..f4aafa48 --- /dev/null +++ b/sources/test/testFiles/placing/test_buildable_tags_type_attributes_match.py @@ -0,0 +1,14 @@ +from conftest import extract_tags_and_attributes +from conftest import BUILDABLE +from conftest import TYPE + +jar = 'placing' + +def test_buildable_tags_type_attributes_match(expected_xml, placing_output_xml): + result_expected = extract_tags_and_attributes(expected_xml, BUILDABLE, TYPE) + result_output = extract_tags_and_attributes(placing_output_xml, BUILDABLE, TYPE) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_buildable_tags_type_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_buildable_tags_type_attributes_match: Different 'element' type attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/placing/test_children_tag_count.py b/sources/test/testFiles/placing/test_children_tag_count.py new file mode 100644 index 00000000..7f384ed0 --- /dev/null +++ b/sources/test/testFiles/placing/test_children_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import CHILDREN + +jar = 'placing' + +def test_children_tags_count(expected_xml, placing_output_xml): + + expected_count = count_tags(expected_xml, CHILDREN) + output_count = count_tags(placing_output_xml, CHILDREN) + + assert expected_count == output_count, f"test_children_tags_count: The number of 'children' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/placing/test_position_tag_count.py b/sources/test/testFiles/placing/test_position_tag_count.py new file mode 100644 index 00000000..8f9a71c5 --- /dev/null +++ b/sources/test/testFiles/placing/test_position_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import POSITION + +jar = 'placing' + +def test_position_tags_count(expected_xml, placing_output_xml): + + expected_count = count_tags(expected_xml, POSITION) + output_count = count_tags(placing_output_xml, POSITION) + + assert expected_count == output_count, f"test_position_tags_count: The number of 'position' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/placing/test_position_tags_x_attributes_match.py b/sources/test/testFiles/placing/test_position_tags_x_attributes_match.py new file mode 100644 index 00000000..aa572597 --- /dev/null +++ b/sources/test/testFiles/placing/test_position_tags_x_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import POSITION +from conftest import X + +jar = 'placing' + +def test_position_tags_x_attributes_match(expected_xml, placing_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, POSITION, X) + result_output = extract_tags_and_attributes_nested(placing_output_xml, BUILDABLE, NONE, POSITION, X) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_position_tags_x_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_position_tags_x_attributes_match: Different 'position' x attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/placing/test_position_tags_y_attributes_match.py b/sources/test/testFiles/placing/test_position_tags_y_attributes_match.py new file mode 100644 index 00000000..cefb0a8f --- /dev/null +++ b/sources/test/testFiles/placing/test_position_tags_y_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import POSITION +from conftest import Y + +jar = 'placing' + +def test_position_tags_y_attributes_match(expected_xml, placing_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, POSITION, Y) + result_output = extract_tags_and_attributes_nested(placing_output_xml, BUILDABLE, NONE, POSITION, Y) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_position_tags_y_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_position_tags_y_attributes_match: Different 'position' y attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/placing/test_position_tags_z_attributes_match.py b/sources/test/testFiles/placing/test_position_tags_z_attributes_match.py new file mode 100644 index 00000000..fbce7cab --- /dev/null +++ b/sources/test/testFiles/placing/test_position_tags_z_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import POSITION +from conftest import Z + +jar = 'placing' + +def test_position_tags_z_attributes_match(expected_xml, placing_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, POSITION, Z) + result_output = extract_tags_and_attributes_nested(placing_output_xml, BUILDABLE, NONE, POSITION, Z) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_position_tags_z_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_position_tags_z_attributes_match: Different 'position' z attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/placing/test_root_element_from_attribute_match.py b/sources/test/testFiles/placing/test_root_element_from_attribute_match.py new file mode 100644 index 00000000..20f6a027 --- /dev/null +++ b/sources/test/testFiles/placing/test_root_element_from_attribute_match.py @@ -0,0 +1,11 @@ +from conftest import root_tag +from conftest import FROM + +jar = 'placing' + +def test_root_element_from_attribute_match(expected_xml, placing_output_xml): + + expected_root_from = root_tag(expected_xml, FROM) + output_root_from = root_tag(placing_output_xml, FROM) + + assert expected_root_from == output_root_from, f"test_root_element_from_attribute_match: The 'from' attribute of the root element does not match. Expected '{expected_root_from}' attribute value, but got '{output_root_from}'" diff --git a/sources/test/testFiles/placing/test_root_element_to_attribute_match.py b/sources/test/testFiles/placing/test_root_element_to_attribute_match.py new file mode 100644 index 00000000..d3d767c4 --- /dev/null +++ b/sources/test/testFiles/placing/test_root_element_to_attribute_match.py @@ -0,0 +1,11 @@ +from conftest import root_tag +from conftest import TO + +jar = 'placing' + +def test_root_element_to_attribute_match(expected_xml, placing_output_xml): + + expected_root_to = root_tag(expected_xml, TO) + output_root_to = root_tag(placing_output_xml, TO) + + assert expected_root_to == output_root_to, f"test_root_element_to_attribute_match: The 'to' attribute of the root element does not match. Expected '{expected_root_to}' attribute value, but got '{output_root_to}'" diff --git a/sources/test/testFiles/placing/test_root_element_version_attribute_match.py b/sources/test/testFiles/placing/test_root_element_version_attribute_match.py new file mode 100644 index 00000000..980d3e1e --- /dev/null +++ b/sources/test/testFiles/placing/test_root_element_version_attribute_match.py @@ -0,0 +1,11 @@ +from conftest import root_tag +from conftest import VERSION + +jar = 'placing' + +def test_root_element_version_attribute_match(expected_xml, placing_output_xml): + + expected_root_version = root_tag(expected_xml, VERSION) + output_root_version = root_tag(placing_output_xml, VERSION) + + assert expected_root_version == output_root_version, f"test_root_element_version_attribute_match: The 'version' attribute of the root element does not match. Expected '{expected_root_version}' attribute value, but got '{output_root_version}'" diff --git a/sources/test/testFiles/placing/test_size_tag_count.py b/sources/test/testFiles/placing/test_size_tag_count.py new file mode 100644 index 00000000..90244f26 --- /dev/null +++ b/sources/test/testFiles/placing/test_size_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import SIZE + +jar = 'placing' + +def test_size_tags_count(expected_xml, placing_output_xml): + + expected_count = count_tags(expected_xml, SIZE) + output_count = count_tags(placing_output_xml, SIZE) + + assert expected_count == output_count, f"The number of 'size' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testFiles/placing/test_size_tags_x_attributes_match.py b/sources/test/testFiles/placing/test_size_tags_x_attributes_match.py new file mode 100644 index 00000000..1031a9a8 --- /dev/null +++ b/sources/test/testFiles/placing/test_size_tags_x_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import SIZE +from conftest import X + +jar = 'placing' + +def test_size_tags_x_attributes_match(expected_xml, placing_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, SIZE, X) + result_output = extract_tags_and_attributes_nested(placing_output_xml, BUILDABLE, NONE, SIZE, X) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_size_tags_x_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_size_tags_x_attributes_match: Different 'size' x attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/placing/test_size_tags_y_attributes_match.py b/sources/test/testFiles/placing/test_size_tags_y_attributes_match.py new file mode 100644 index 00000000..51c575bb --- /dev/null +++ b/sources/test/testFiles/placing/test_size_tags_y_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import SIZE +from conftest import Y + +jar = 'placing' + +def test_size_tags_y_attributes_match(expected_xml, placing_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, SIZE, Y) + result_output = extract_tags_and_attributes_nested(placing_output_xml, BUILDABLE, NONE, SIZE, Y) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_size_tags_y_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_size_tags_y_attributes_match: Different 'size' y attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/placing/test_size_tags_z_attributes_match.py b/sources/test/testFiles/placing/test_size_tags_z_attributes_match.py new file mode 100644 index 00000000..fde754a0 --- /dev/null +++ b/sources/test/testFiles/placing/test_size_tags_z_attributes_match.py @@ -0,0 +1,16 @@ +from conftest import extract_tags_and_attributes_nested +from conftest import BUILDABLE +from conftest import NONE +from conftest import SIZE +from conftest import Z + +jar = 'placing' + +def test_size_tags_z_attributes_match(expected_xml, placing_output_xml): + result_expected = extract_tags_and_attributes_nested(expected_xml, BUILDABLE, NONE, SIZE, Z) + result_output = extract_tags_and_attributes_nested(placing_output_xml, BUILDABLE, NONE, SIZE, Z) + + assert set(result_expected.keys()) == set(result_output.keys()), f"test_size_tags_z_attributes_match: The parent map is different between the expected and generated output" + + for key in result_expected.keys(): + assert set(result_expected[key]) == set(result_output[key]), f"test_size_tags_z_attributes_match: Different 'size' z attribute value. Path to the different value:\n {key} " diff --git a/sources/test/testFiles/rendering/test_TEMP_dir_exist.py b/sources/test/testFiles/rendering/test_TEMP_dir_exist.py new file mode 100644 index 00000000..97a5bfb2 --- /dev/null +++ b/sources/test/testFiles/rendering/test_TEMP_dir_exist.py @@ -0,0 +1,7 @@ +import os + +jar = 'rendering' + +def test_TEMP_dir_exist(rendering_output_path): + + assert os.path.isdir(rendering_output_path + "/TEMP"), 'test_TEMP_dir_exist: The TEMP directory is not exist in output world folder' \ No newline at end of file diff --git a/sources/test/testFiles/rendering/test_blocks00_file_exist.py b/sources/test/testFiles/rendering/test_blocks00_file_exist.py new file mode 100644 index 00000000..9051bb15 --- /dev/null +++ b/sources/test/testFiles/rendering/test_blocks00_file_exist.py @@ -0,0 +1,10 @@ +import os + +jar = 'rendering' + +def test_blocks00_file_exist(rendering_output_path): + + assert os.path.isfile(rendering_output_path + "/TEMP/blocks.0.0.csv"), 'test_r00_file_exist: The blocks0.0.csv file is not exist in output world' + + + \ No newline at end of file diff --git a/sources/test/testFiles/rendering/test_blocks00_file_not_empty.py b/sources/test/testFiles/rendering/test_blocks00_file_not_empty.py new file mode 100644 index 00000000..f78cac89 --- /dev/null +++ b/sources/test/testFiles/rendering/test_blocks00_file_not_empty.py @@ -0,0 +1,13 @@ +import os + +jar = 'rendering' + +def test_blocks00_file_not_empty(rendering_output_path): + + notEmpty = False + if (os.stat(rendering_output_path + "/TEMP/blocks.0.0.csv").st_size != 0): + notEmpty = True + + assert notEmpty == True, 'test_blocks00_file_not_empty: The blocks.0.0.csv file is empty.' + + \ No newline at end of file diff --git a/sources/test/testFiles/rendering/test_check_files_modification_time.py b/sources/test/testFiles/rendering/test_check_files_modification_time.py new file mode 100644 index 00000000..6d635b81 --- /dev/null +++ b/sources/test/testFiles/rendering/test_check_files_modification_time.py @@ -0,0 +1,17 @@ +import os +import datetime + +jar = 'rendering' + +def test_check_files_modification_time(rendering_output_path): + output_files = [] + for root, dirs, files in os.walk(rendering_output_path): + for file in files: + output_files.append(os.path.join(root, file)) + + for file in output_files: + mtime = os.path.getmtime(file) + mod_time = datetime.datetime.fromtimestamp(mtime) + curr_time = datetime.datetime.now() + diff = curr_time - mod_time + assert diff.seconds <= 30, f"test_check_files_modification_time: '{file}' file was last modified more than 30 minutes ago" diff --git a/sources/test/testFiles/rendering/test_level_file_exist.py b/sources/test/testFiles/rendering/test_level_file_exist.py new file mode 100644 index 00000000..b543c6d6 --- /dev/null +++ b/sources/test/testFiles/rendering/test_level_file_exist.py @@ -0,0 +1,9 @@ +import os + +jar = 'rendering' + +def test_level_file_exist(rendering_output_path): + + assert os.path.isfile(rendering_output_path + "/level.dat"), 'test_level_file_exist: The level.dat file is not exist in output world' + + \ No newline at end of file diff --git a/sources/test/testFiles/rendering/test_level_file_not_empty.py b/sources/test/testFiles/rendering/test_level_file_not_empty.py new file mode 100644 index 00000000..fa36dcc2 --- /dev/null +++ b/sources/test/testFiles/rendering/test_level_file_not_empty.py @@ -0,0 +1,13 @@ +import os + +jar = 'rendering' + +def test_level_file_not_empty(rendering_output_path): + + notEmpty = False + if (os.stat(rendering_output_path + "/level.dat").st_size != 0): + notEmpty = True + + assert notEmpty == True, 'test_level_file_not_empty: The level.dat file is empty.' + + \ No newline at end of file diff --git a/sources/test/testFiles/rendering/test_number_of_files_in_world_folder.py b/sources/test/testFiles/rendering/test_number_of_files_in_world_folder.py new file mode 100644 index 00000000..0d4fd52e --- /dev/null +++ b/sources/test/testFiles/rendering/test_number_of_files_in_world_folder.py @@ -0,0 +1,16 @@ +import os + +jar = 'rendering' + +def test_number_of_files_in_world_folder(expected_rendering_path, rendering_output_path): + expected_files = [] + for root, dirs, files in os.walk(expected_rendering_path): + for file in files: + expected_files.append(os.path.join(root, file)) + + output_files = [] + for root, dirs, files in os.walk(rendering_output_path): + for file in files: + output_files.append(os.path.join(root, file)) + + assert len(expected_files) == len(output_files), f"test_number_of_files_in_world_folder: Expected {len(expected_files)} files in world folder, but found {len(output_files)}" diff --git a/sources/test/testFiles/rendering/test_r00_file_exist.py b/sources/test/testFiles/rendering/test_r00_file_exist.py new file mode 100644 index 00000000..97acbb58 --- /dev/null +++ b/sources/test/testFiles/rendering/test_r00_file_exist.py @@ -0,0 +1,10 @@ +import os + +jar = 'rendering' + +def test_r00_file_exist(rendering_output_path): + + assert os.path.isfile(rendering_output_path + "/region/r.0.0.mca"), 'test_r00_file_exist: The r.0.0 file is not exist in output world' + + + \ No newline at end of file diff --git a/sources/test/testFiles/rendering/test_r00_file_not_empty.py b/sources/test/testFiles/rendering/test_r00_file_not_empty.py new file mode 100644 index 00000000..d3a912d1 --- /dev/null +++ b/sources/test/testFiles/rendering/test_r00_file_not_empty.py @@ -0,0 +1,13 @@ +import os + +jar = 'rendering' + +def test_r00_file_not_empty(rendering_output_path): + + notEmpty = False + if (os.stat(rendering_output_path + "/region/r.0.0.mca").st_size != 0): + notEmpty = True + + assert notEmpty == True, 'test_r00_file_not_empty: The r0.0.mca file is empty.' + + \ No newline at end of file diff --git a/sources/test/testFiles/rendering/test_region_dir_exist.py b/sources/test/testFiles/rendering/test_region_dir_exist.py new file mode 100644 index 00000000..2762099d --- /dev/null +++ b/sources/test/testFiles/rendering/test_region_dir_exist.py @@ -0,0 +1,7 @@ +import os + +jar = 'rendering' + +def test_region_dir_exist(rendering_output_path): + + assert os.path.isdir(rendering_output_path + "/region"), 'test_region_dir_exist: The region directory is not exist in output world folder' diff --git a/sources/test/testFiles/rendering/test_world_dir_exist.py b/sources/test/testFiles/rendering/test_world_dir_exist.py new file mode 100644 index 00000000..fe8b461d --- /dev/null +++ b/sources/test/testFiles/rendering/test_world_dir_exist.py @@ -0,0 +1,7 @@ +import os + +jar = 'rendering' + +def test_world_dir_exist(rendering_output_path): + + assert os.path.isdir(rendering_output_path), 'test_world_dir_exist: The output world directory is not exist' diff --git a/sources/test/testing/converter/TestProject_Simple1.graph b/sources/test/testing/converter/TestProject_Simple1.graph new file mode 100644 index 00000000..d57778b4 Binary files /dev/null and b/sources/test/testing/converter/TestProject_Simple1.graph differ diff --git a/sources/test/testing/converter/converterToMapping.xml b/sources/test/testing/converter/converterToMapping.xml new file mode 100644 index 00000000..8651e831 --- /dev/null +++ b/sources/test/testing/converter/converterToMapping.xml @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/test/testing/converter/expected.xml b/sources/test/testing/converter/expected.xml new file mode 100644 index 00000000..8651e831 --- /dev/null +++ b/sources/test/testing/converter/expected.xml @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/test/testing/mapping/__pycache__/test_attribute_tag_count.cpython-311.pyc b/sources/test/testing/mapping/__pycache__/test_attribute_tag_count.cpython-311.pyc new file mode 100644 index 00000000..8562a8d9 Binary files /dev/null and b/sources/test/testing/mapping/__pycache__/test_attribute_tag_count.cpython-311.pyc differ diff --git a/sources/test/testing/mapping/mappingToPlacing.xml b/sources/test/testing/mapping/mappingToPlacing.xml new file mode 100644 index 00000000..d5ea3302 --- /dev/null +++ b/sources/test/testing/mapping/mappingToPlacing.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/test/testing/mapping/test_attribute_tag_count.py b/sources/test/testing/mapping/test_attribute_tag_count.py new file mode 100644 index 00000000..b3587e4c --- /dev/null +++ b/sources/test/testing/mapping/test_attribute_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import ATTRIBUTE + +jar = 'mapping' + +def test_attribute_tags_count(expected_xml, mapping_output_xml): + + expected_count = count_tags(expected_xml, ATTRIBUTE) + output_count = count_tags(mapping_output_xml, ATTRIBUTE) + + assert expected_count == output_count, f"test_attribute_tags_count: The number of 'attribute' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testing/placing/__pycache__/test_attribute_tag_count.cpython-311.pyc b/sources/test/testing/placing/__pycache__/test_attribute_tag_count.cpython-311.pyc new file mode 100644 index 00000000..4149fe04 Binary files /dev/null and b/sources/test/testing/placing/__pycache__/test_attribute_tag_count.cpython-311.pyc differ diff --git a/sources/test/testing/placing/placingToRendering.xml b/sources/test/testing/placing/placingToRendering.xml new file mode 100644 index 00000000..366da638 --- /dev/null +++ b/sources/test/testing/placing/placingToRendering.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/test/testing/placing/test_attribute_tag_count.py b/sources/test/testing/placing/test_attribute_tag_count.py new file mode 100644 index 00000000..8738de72 --- /dev/null +++ b/sources/test/testing/placing/test_attribute_tag_count.py @@ -0,0 +1,12 @@ +from conftest import count_tags +from conftest import ATTRIBUTE + +jar = 'placing' + +def test_attribute_tags_count(expected_xml, placing_output_xml): + + expected_count = count_tags(expected_xml, ATTRIBUTE) + output_count = count_tags(placing_output_xml, ATTRIBUTE) + + assert expected_count == output_count, f"test_attribute_tags_count: The number of 'attribute' tags does not match. Expected {expected_count}, but got {output_count} tags." + diff --git a/sources/test/testing/rendering/world/TEMP/blocks.0.0.csv b/sources/test/testing/rendering/world/TEMP/blocks.0.0.csv new file mode 100644 index 00000000..e41c099d --- /dev/null +++ b/sources/test/testing/rendering/world/TEMP/blocks.0.0.csv @@ -0,0 +1,3135 @@ +minecraft:stone_bricks;;3;61;3;NULL +minecraft:stone_bricks;;3;61;4;NULL +minecraft:stone_bricks;;3;61;5;NULL +minecraft:stone_bricks;;3;61;6;NULL +minecraft:stone_bricks;;3;61;7;NULL +minecraft:stone_bricks;;3;61;8;NULL +minecraft:stone_bricks;;3;61;9;NULL +minecraft:stone_bricks;;3;61;10;NULL +minecraft:stone_bricks;;3;61;11;NULL +minecraft:stone_bricks;;3;61;12;NULL +minecraft:stone_bricks;;3;61;13;NULL +minecraft:stone_bricks;;3;61;14;NULL +minecraft:stone_bricks;;3;61;15;NULL +minecraft:stone_bricks;;3;61;16;NULL +minecraft:stone_bricks;;3;61;17;NULL +minecraft:stone_bricks;;3;61;18;NULL +minecraft:stone_bricks;;3;61;19;NULL +minecraft:stone_bricks;;3;61;20;NULL +minecraft:stone_bricks;;3;61;21;NULL +minecraft:stone_bricks;;3;61;22;NULL +minecraft:stone_bricks;;3;61;23;NULL +minecraft:stone_bricks;;3;61;24;NULL +minecraft:stone_bricks;;3;61;25;NULL +minecraft:stone_bricks;;3;61;26;NULL +minecraft:stone_bricks;;3;61;27;NULL +minecraft:stone_bricks;;3;61;28;NULL +minecraft:stone_bricks;;3;61;29;NULL +minecraft:stone_bricks;;4;61;3;NULL +minecraft:stone;;4;61;4;NULL +minecraft:stone;;4;61;5;NULL +minecraft:stone;;4;61;6;NULL +minecraft:stone;;4;61;7;NULL +minecraft:stone;;4;61;8;NULL +minecraft:stone;;4;61;9;NULL +minecraft:stone;;4;61;10;NULL +minecraft:stone;;4;61;11;NULL +minecraft:stone;;4;61;12;NULL +minecraft:stone;;4;61;13;NULL +minecraft:stone;;4;61;14;NULL +minecraft:stone;;4;61;15;NULL +minecraft:stone;;4;61;16;NULL +minecraft:stone;;4;61;17;NULL +minecraft:stone;;4;61;18;NULL +minecraft:stone;;4;61;19;NULL +minecraft:stone;;4;61;20;NULL +minecraft:stone;;4;61;21;NULL +minecraft:stone;;4;61;22;NULL +minecraft:stone;;4;61;23;NULL +minecraft:stone;;4;61;24;NULL +minecraft:stone;;4;61;25;NULL +minecraft:stone;;4;61;26;NULL +minecraft:stone;;4;61;27;NULL +minecraft:stone;;4;61;28;NULL +minecraft:stone_bricks;;4;61;29;NULL +minecraft:stone_bricks;;5;61;3;NULL +minecraft:stone;;5;61;4;NULL +minecraft:stone;;5;61;5;NULL +minecraft:stone;;5;61;6;NULL +minecraft:stone;;5;61;7;NULL +minecraft:stone;;5;61;8;NULL +minecraft:stone;;5;61;9;NULL +minecraft:stone;;5;61;10;NULL +minecraft:stone;;5;61;11;NULL +minecraft:stone;;5;61;12;NULL +minecraft:stone;;5;61;13;NULL +minecraft:stone;;5;61;14;NULL +minecraft:stone;;5;61;15;NULL +minecraft:stone;;5;61;16;NULL +minecraft:stone;;5;61;17;NULL +minecraft:stone;;5;61;18;NULL +minecraft:stone;;5;61;19;NULL +minecraft:stone;;5;61;20;NULL +minecraft:stone;;5;61;21;NULL +minecraft:stone;;5;61;22;NULL +minecraft:stone;;5;61;23;NULL +minecraft:stone;;5;61;24;NULL +minecraft:stone;;5;61;25;NULL +minecraft:stone;;5;61;26;NULL +minecraft:stone;;5;61;27;NULL +minecraft:stone;;5;61;28;NULL +minecraft:stone_bricks;;5;61;29;NULL +minecraft:stone_bricks;;6;61;3;NULL +minecraft:stone;;6;61;4;NULL +minecraft:stone;;6;61;5;NULL +minecraft:stone;;6;61;6;NULL +minecraft:stone;;6;61;7;NULL +minecraft:stone;;6;61;8;NULL +minecraft:stone;;6;61;9;NULL +minecraft:stone;;6;61;10;NULL +minecraft:stone;;6;61;11;NULL +minecraft:stone;;6;61;12;NULL +minecraft:stone;;6;61;13;NULL +minecraft:stone;;6;61;14;NULL +minecraft:stone;;6;61;15;NULL +minecraft:stone;;6;61;16;NULL +minecraft:stone;;6;61;17;NULL +minecraft:stone;;6;61;18;NULL +minecraft:stone;;6;61;19;NULL +minecraft:stone;;6;61;20;NULL +minecraft:stone;;6;61;21;NULL +minecraft:stone;;6;61;22;NULL +minecraft:stone;;6;61;23;NULL +minecraft:stone;;6;61;24;NULL +minecraft:stone;;6;61;25;NULL +minecraft:stone;;6;61;26;NULL +minecraft:stone;;6;61;27;NULL +minecraft:stone;;6;61;28;NULL +minecraft:stone_bricks;;6;61;29;NULL +minecraft:stone_bricks;;7;61;3;NULL +minecraft:stone;;7;61;4;NULL +minecraft:stone;;7;61;5;NULL +minecraft:stone;;7;61;6;NULL +minecraft:stone;;7;61;7;NULL +minecraft:stone;;7;61;8;NULL +minecraft:stone;;7;61;9;NULL +minecraft:stone;;7;61;10;NULL +minecraft:stone;;7;61;11;NULL +minecraft:stone;;7;61;12;NULL +minecraft:stone;;7;61;13;NULL +minecraft:stone;;7;61;14;NULL +minecraft:stone;;7;61;15;NULL +minecraft:stone;;7;61;16;NULL +minecraft:stone;;7;61;17;NULL +minecraft:stone;;7;61;18;NULL +minecraft:stone;;7;61;19;NULL +minecraft:stone;;7;61;20;NULL +minecraft:stone;;7;61;21;NULL +minecraft:stone;;7;61;22;NULL +minecraft:stone;;7;61;23;NULL +minecraft:stone;;7;61;24;NULL +minecraft:stone;;7;61;25;NULL +minecraft:stone;;7;61;26;NULL +minecraft:stone;;7;61;27;NULL +minecraft:stone;;7;61;28;NULL +minecraft:stone_bricks;;7;61;29;NULL +minecraft:stone_bricks;;8;61;3;NULL +minecraft:stone;;8;61;4;NULL +minecraft:stone;;8;61;5;NULL +minecraft:stone;;8;61;6;NULL +minecraft:stone;;8;61;7;NULL +minecraft:stone;;8;61;8;NULL +minecraft:stone;;8;61;9;NULL +minecraft:stone;;8;61;10;NULL +minecraft:stone;;8;61;11;NULL +minecraft:stone;;8;61;12;NULL +minecraft:stone;;8;61;13;NULL +minecraft:stone;;8;61;14;NULL +minecraft:stone;;8;61;15;NULL +minecraft:stone;;8;61;16;NULL +minecraft:stone;;8;61;17;NULL +minecraft:stone;;8;61;18;NULL +minecraft:stone;;8;61;19;NULL +minecraft:stone;;8;61;20;NULL +minecraft:stone;;8;61;21;NULL +minecraft:stone;;8;61;22;NULL +minecraft:stone;;8;61;23;NULL +minecraft:stone;;8;61;24;NULL +minecraft:stone;;8;61;25;NULL +minecraft:stone;;8;61;26;NULL +minecraft:stone;;8;61;27;NULL +minecraft:stone;;8;61;28;NULL +minecraft:stone_bricks;;8;61;29;NULL +minecraft:stone_bricks;;9;61;3;NULL +minecraft:stone;;9;61;4;NULL +minecraft:stone;;9;61;5;NULL +minecraft:stone;;9;61;6;NULL +minecraft:stone;;9;61;7;NULL +minecraft:stone;;9;61;8;NULL +minecraft:stone;;9;61;9;NULL +minecraft:stone;;9;61;10;NULL +minecraft:stone;;9;61;11;NULL +minecraft:stone;;9;61;12;NULL +minecraft:stone;;9;61;13;NULL +minecraft:stone;;9;61;14;NULL +minecraft:stone;;9;61;15;NULL +minecraft:stone;;9;61;16;NULL +minecraft:stone;;9;61;17;NULL +minecraft:stone;;9;61;18;NULL +minecraft:stone;;9;61;19;NULL +minecraft:stone;;9;61;20;NULL +minecraft:stone;;9;61;21;NULL +minecraft:stone;;9;61;22;NULL +minecraft:stone;;9;61;23;NULL +minecraft:stone;;9;61;24;NULL +minecraft:stone;;9;61;25;NULL +minecraft:stone;;9;61;26;NULL +minecraft:stone;;9;61;27;NULL +minecraft:stone;;9;61;28;NULL +minecraft:stone_bricks;;9;61;29;NULL +minecraft:stone_bricks;;10;61;3;NULL +minecraft:stone;;10;61;4;NULL +minecraft:stone;;10;61;5;NULL +minecraft:stone;;10;61;6;NULL +minecraft:stone;;10;61;7;NULL +minecraft:stone;;10;61;8;NULL +minecraft:stone;;10;61;9;NULL +minecraft:stone;;10;61;10;NULL +minecraft:stone;;10;61;11;NULL +minecraft:stone;;10;61;12;NULL +minecraft:stone;;10;61;13;NULL +minecraft:stone;;10;61;14;NULL +minecraft:stone;;10;61;15;NULL +minecraft:stone;;10;61;16;NULL +minecraft:stone;;10;61;17;NULL +minecraft:stone;;10;61;18;NULL +minecraft:stone;;10;61;19;NULL +minecraft:stone;;10;61;20;NULL +minecraft:stone;;10;61;21;NULL +minecraft:stone;;10;61;22;NULL +minecraft:stone;;10;61;23;NULL +minecraft:stone;;10;61;24;NULL +minecraft:stone;;10;61;25;NULL +minecraft:stone;;10;61;26;NULL +minecraft:stone;;10;61;27;NULL +minecraft:stone;;10;61;28;NULL +minecraft:stone_bricks;;10;61;29;NULL +minecraft:stone_bricks;;11;61;3;NULL +minecraft:stone;;11;61;4;NULL +minecraft:stone;;11;61;5;NULL +minecraft:stone;;11;61;6;NULL +minecraft:stone;;11;61;7;NULL +minecraft:stone;;11;61;8;NULL +minecraft:stone;;11;61;9;NULL +minecraft:stone;;11;61;10;NULL +minecraft:stone;;11;61;11;NULL +minecraft:stone;;11;61;12;NULL +minecraft:stone;;11;61;13;NULL +minecraft:stone;;11;61;14;NULL +minecraft:stone;;11;61;15;NULL +minecraft:stone;;11;61;16;NULL +minecraft:stone;;11;61;17;NULL +minecraft:stone;;11;61;18;NULL +minecraft:stone;;11;61;19;NULL +minecraft:stone;;11;61;20;NULL +minecraft:stone;;11;61;21;NULL +minecraft:stone;;11;61;22;NULL +minecraft:stone;;11;61;23;NULL +minecraft:stone;;11;61;24;NULL +minecraft:stone;;11;61;25;NULL +minecraft:stone;;11;61;26;NULL +minecraft:stone;;11;61;27;NULL +minecraft:stone;;11;61;28;NULL +minecraft:stone_bricks;;11;61;29;NULL +minecraft:stone_bricks;;12;61;3;NULL +minecraft:stone;;12;61;4;NULL +minecraft:stone;;12;61;5;NULL +minecraft:stone;;12;61;6;NULL +minecraft:stone;;12;61;7;NULL +minecraft:stone;;12;61;8;NULL +minecraft:stone;;12;61;9;NULL +minecraft:stone;;12;61;10;NULL +minecraft:stone;;12;61;11;NULL +minecraft:stone;;12;61;12;NULL +minecraft:stone;;12;61;13;NULL +minecraft:stone;;12;61;14;NULL +minecraft:stone;;12;61;15;NULL +minecraft:stone;;12;61;16;NULL +minecraft:stone;;12;61;17;NULL +minecraft:stone;;12;61;18;NULL +minecraft:stone;;12;61;19;NULL +minecraft:stone;;12;61;20;NULL +minecraft:stone;;12;61;21;NULL +minecraft:stone;;12;61;22;NULL +minecraft:stone;;12;61;23;NULL +minecraft:stone;;12;61;24;NULL +minecraft:stone;;12;61;25;NULL +minecraft:stone;;12;61;26;NULL +minecraft:stone;;12;61;27;NULL +minecraft:stone;;12;61;28;NULL +minecraft:stone_bricks;;12;61;29;NULL +minecraft:stone_bricks;;13;61;3;NULL +minecraft:stone;;13;61;4;NULL +minecraft:stone;;13;61;5;NULL +minecraft:stone;;13;61;6;NULL +minecraft:stone;;13;61;7;NULL +minecraft:stone;;13;61;8;NULL +minecraft:stone;;13;61;9;NULL +minecraft:stone;;13;61;10;NULL +minecraft:stone;;13;61;11;NULL +minecraft:stone;;13;61;12;NULL +minecraft:stone;;13;61;13;NULL +minecraft:stone;;13;61;14;NULL +minecraft:stone;;13;61;15;NULL +minecraft:stone;;13;61;16;NULL +minecraft:stone;;13;61;17;NULL +minecraft:stone;;13;61;18;NULL +minecraft:stone;;13;61;19;NULL +minecraft:stone;;13;61;20;NULL +minecraft:stone;;13;61;21;NULL +minecraft:stone;;13;61;22;NULL +minecraft:stone;;13;61;23;NULL +minecraft:stone;;13;61;24;NULL +minecraft:stone;;13;61;25;NULL +minecraft:stone;;13;61;26;NULL +minecraft:stone;;13;61;27;NULL +minecraft:stone;;13;61;28;NULL +minecraft:stone_bricks;;13;61;29;NULL +minecraft:stone_bricks;;14;61;3;NULL +minecraft:stone;;14;61;4;NULL +minecraft:stone;;14;61;5;NULL +minecraft:stone;;14;61;6;NULL +minecraft:stone;;14;61;7;NULL +minecraft:stone;;14;61;8;NULL +minecraft:stone;;14;61;9;NULL +minecraft:stone;;14;61;10;NULL +minecraft:stone;;14;61;11;NULL +minecraft:stone;;14;61;12;NULL +minecraft:stone;;14;61;13;NULL +minecraft:stone;;14;61;14;NULL +minecraft:stone;;14;61;15;NULL +minecraft:stone;;14;61;16;NULL +minecraft:stone;;14;61;17;NULL +minecraft:stone;;14;61;18;NULL +minecraft:stone;;14;61;19;NULL +minecraft:stone;;14;61;20;NULL +minecraft:stone;;14;61;21;NULL +minecraft:stone;;14;61;22;NULL +minecraft:stone;;14;61;23;NULL +minecraft:stone;;14;61;24;NULL +minecraft:stone;;14;61;25;NULL +minecraft:stone;;14;61;26;NULL +minecraft:stone;;14;61;27;NULL +minecraft:stone;;14;61;28;NULL +minecraft:stone_bricks;;14;61;29;NULL +minecraft:stone_bricks;;15;61;3;NULL +minecraft:stone;;15;61;4;NULL +minecraft:stone;;15;61;5;NULL +minecraft:stone;;15;61;6;NULL +minecraft:stone;;15;61;7;NULL +minecraft:stone;;15;61;8;NULL +minecraft:stone;;15;61;9;NULL +minecraft:stone;;15;61;10;NULL +minecraft:stone;;15;61;11;NULL +minecraft:stone;;15;61;12;NULL +minecraft:stone;;15;61;13;NULL +minecraft:stone;;15;61;14;NULL +minecraft:stone;;15;61;15;NULL +minecraft:stone;;15;61;16;NULL +minecraft:stone;;15;61;17;NULL +minecraft:stone;;15;61;18;NULL +minecraft:stone;;15;61;19;NULL +minecraft:stone;;15;61;20;NULL +minecraft:stone;;15;61;21;NULL +minecraft:stone;;15;61;22;NULL +minecraft:stone;;15;61;23;NULL +minecraft:stone;;15;61;24;NULL +minecraft:stone;;15;61;25;NULL +minecraft:stone;;15;61;26;NULL +minecraft:stone;;15;61;27;NULL +minecraft:stone;;15;61;28;NULL +minecraft:stone_bricks;;15;61;29;NULL +minecraft:stone_bricks;;16;61;3;NULL +minecraft:stone;;16;61;4;NULL +minecraft:stone;;16;61;5;NULL +minecraft:stone;;16;61;6;NULL +minecraft:stone;;16;61;7;NULL +minecraft:stone;;16;61;8;NULL +minecraft:stone;;16;61;9;NULL +minecraft:stone;;16;61;10;NULL +minecraft:stone;;16;61;11;NULL +minecraft:stone;;16;61;12;NULL +minecraft:stone;;16;61;13;NULL +minecraft:stone;;16;61;14;NULL +minecraft:stone;;16;61;15;NULL +minecraft:stone;;16;61;16;NULL +minecraft:stone;;16;61;17;NULL +minecraft:stone;;16;61;18;NULL +minecraft:stone;;16;61;19;NULL +minecraft:stone;;16;61;20;NULL +minecraft:stone;;16;61;21;NULL +minecraft:stone;;16;61;22;NULL +minecraft:stone;;16;61;23;NULL +minecraft:stone;;16;61;24;NULL +minecraft:stone;;16;61;25;NULL +minecraft:stone;;16;61;26;NULL +minecraft:stone;;16;61;27;NULL +minecraft:stone;;16;61;28;NULL +minecraft:stone_bricks;;16;61;29;NULL +minecraft:stone_bricks;;17;61;3;NULL +minecraft:stone;;17;61;4;NULL +minecraft:stone;;17;61;5;NULL +minecraft:stone;;17;61;6;NULL +minecraft:stone;;17;61;7;NULL +minecraft:stone;;17;61;8;NULL +minecraft:stone;;17;61;9;NULL +minecraft:stone;;17;61;10;NULL +minecraft:stone;;17;61;11;NULL +minecraft:stone;;17;61;12;NULL +minecraft:stone;;17;61;13;NULL +minecraft:stone;;17;61;14;NULL +minecraft:stone;;17;61;15;NULL +minecraft:stone;;17;61;16;NULL +minecraft:stone;;17;61;17;NULL +minecraft:stone;;17;61;18;NULL +minecraft:stone;;17;61;19;NULL +minecraft:stone;;17;61;20;NULL +minecraft:stone;;17;61;21;NULL +minecraft:stone;;17;61;22;NULL +minecraft:stone;;17;61;23;NULL +minecraft:stone;;17;61;24;NULL +minecraft:stone;;17;61;25;NULL +minecraft:stone;;17;61;26;NULL +minecraft:stone;;17;61;27;NULL +minecraft:stone;;17;61;28;NULL +minecraft:stone_bricks;;17;61;29;NULL +minecraft:stone_bricks;;18;61;3;NULL +minecraft:stone;;18;61;4;NULL +minecraft:stone;;18;61;5;NULL +minecraft:stone;;18;61;6;NULL +minecraft:stone;;18;61;7;NULL +minecraft:stone;;18;61;8;NULL +minecraft:stone;;18;61;9;NULL +minecraft:stone;;18;61;10;NULL +minecraft:stone;;18;61;11;NULL +minecraft:stone;;18;61;12;NULL +minecraft:stone;;18;61;13;NULL +minecraft:stone;;18;61;14;NULL +minecraft:stone;;18;61;15;NULL +minecraft:stone;;18;61;16;NULL +minecraft:stone;;18;61;17;NULL +minecraft:stone;;18;61;18;NULL +minecraft:stone;;18;61;19;NULL +minecraft:stone;;18;61;20;NULL +minecraft:stone;;18;61;21;NULL +minecraft:stone;;18;61;22;NULL +minecraft:stone;;18;61;23;NULL +minecraft:stone;;18;61;24;NULL +minecraft:stone;;18;61;25;NULL +minecraft:stone;;18;61;26;NULL +minecraft:stone;;18;61;27;NULL +minecraft:stone;;18;61;28;NULL +minecraft:stone_bricks;;18;61;29;NULL +minecraft:stone_bricks;;19;61;3;NULL +minecraft:stone;;19;61;4;NULL +minecraft:stone;;19;61;5;NULL +minecraft:stone;;19;61;6;NULL +minecraft:stone;;19;61;7;NULL +minecraft:stone;;19;61;8;NULL +minecraft:stone;;19;61;9;NULL +minecraft:stone;;19;61;10;NULL +minecraft:stone;;19;61;11;NULL +minecraft:stone;;19;61;12;NULL +minecraft:stone;;19;61;13;NULL +minecraft:stone;;19;61;14;NULL +minecraft:stone;;19;61;15;NULL +minecraft:stone;;19;61;16;NULL +minecraft:stone;;19;61;17;NULL +minecraft:stone;;19;61;18;NULL +minecraft:stone;;19;61;19;NULL +minecraft:stone;;19;61;20;NULL +minecraft:stone;;19;61;21;NULL +minecraft:stone;;19;61;22;NULL +minecraft:stone;;19;61;23;NULL +minecraft:stone;;19;61;24;NULL +minecraft:stone;;19;61;25;NULL +minecraft:stone;;19;61;26;NULL +minecraft:stone;;19;61;27;NULL +minecraft:stone;;19;61;28;NULL +minecraft:stone_bricks;;19;61;29;NULL +minecraft:stone_bricks;;20;61;3;NULL +minecraft:stone;;20;61;4;NULL +minecraft:stone;;20;61;5;NULL +minecraft:stone;;20;61;6;NULL +minecraft:stone;;20;61;7;NULL +minecraft:stone;;20;61;8;NULL +minecraft:stone;;20;61;9;NULL +minecraft:stone;;20;61;10;NULL +minecraft:stone;;20;61;11;NULL +minecraft:stone;;20;61;12;NULL +minecraft:stone;;20;61;13;NULL +minecraft:stone;;20;61;14;NULL +minecraft:stone;;20;61;15;NULL +minecraft:stone;;20;61;16;NULL +minecraft:stone;;20;61;17;NULL +minecraft:stone;;20;61;18;NULL +minecraft:stone;;20;61;19;NULL +minecraft:stone;;20;61;20;NULL +minecraft:stone;;20;61;21;NULL +minecraft:stone;;20;61;22;NULL +minecraft:stone;;20;61;23;NULL +minecraft:stone;;20;61;24;NULL +minecraft:stone;;20;61;25;NULL +minecraft:stone;;20;61;26;NULL +minecraft:stone;;20;61;27;NULL +minecraft:stone;;20;61;28;NULL +minecraft:stone_bricks;;20;61;29;NULL +minecraft:stone_bricks;;21;61;3;NULL +minecraft:stone;;21;61;4;NULL +minecraft:stone;;21;61;5;NULL +minecraft:stone;;21;61;6;NULL +minecraft:stone;;21;61;7;NULL +minecraft:stone;;21;61;8;NULL +minecraft:stone;;21;61;9;NULL +minecraft:stone;;21;61;10;NULL +minecraft:stone;;21;61;11;NULL +minecraft:stone;;21;61;12;NULL +minecraft:stone;;21;61;13;NULL +minecraft:stone;;21;61;14;NULL +minecraft:stone;;21;61;15;NULL +minecraft:stone;;21;61;16;NULL +minecraft:stone;;21;61;17;NULL +minecraft:stone;;21;61;18;NULL +minecraft:stone;;21;61;19;NULL +minecraft:stone;;21;61;20;NULL +minecraft:stone;;21;61;21;NULL +minecraft:stone;;21;61;22;NULL +minecraft:stone;;21;61;23;NULL +minecraft:stone;;21;61;24;NULL +minecraft:stone;;21;61;25;NULL +minecraft:stone;;21;61;26;NULL +minecraft:stone;;21;61;27;NULL +minecraft:stone;;21;61;28;NULL +minecraft:stone_bricks;;21;61;29;NULL +minecraft:stone_bricks;;22;61;3;NULL +minecraft:stone;;22;61;4;NULL +minecraft:stone;;22;61;5;NULL +minecraft:stone;;22;61;6;NULL +minecraft:stone;;22;61;7;NULL +minecraft:stone;;22;61;8;NULL +minecraft:stone;;22;61;9;NULL +minecraft:stone;;22;61;10;NULL +minecraft:stone;;22;61;11;NULL +minecraft:stone;;22;61;12;NULL +minecraft:stone;;22;61;13;NULL +minecraft:stone;;22;61;14;NULL +minecraft:stone;;22;61;15;NULL +minecraft:stone;;22;61;16;NULL +minecraft:stone;;22;61;17;NULL +minecraft:stone;;22;61;18;NULL +minecraft:stone;;22;61;19;NULL +minecraft:stone;;22;61;20;NULL +minecraft:stone;;22;61;21;NULL +minecraft:stone;;22;61;22;NULL +minecraft:stone;;22;61;23;NULL +minecraft:stone;;22;61;24;NULL +minecraft:stone;;22;61;25;NULL +minecraft:stone;;22;61;26;NULL +minecraft:stone;;22;61;27;NULL +minecraft:stone;;22;61;28;NULL +minecraft:stone_bricks;;22;61;29;NULL +minecraft:stone_bricks;;23;61;3;NULL +minecraft:stone;;23;61;4;NULL +minecraft:stone;;23;61;5;NULL +minecraft:stone;;23;61;6;NULL +minecraft:stone;;23;61;7;NULL +minecraft:stone;;23;61;8;NULL +minecraft:stone;;23;61;9;NULL +minecraft:stone;;23;61;10;NULL +minecraft:stone;;23;61;11;NULL +minecraft:stone;;23;61;12;NULL +minecraft:stone;;23;61;13;NULL +minecraft:stone;;23;61;14;NULL +minecraft:stone;;23;61;15;NULL +minecraft:stone;;23;61;16;NULL +minecraft:stone;;23;61;17;NULL +minecraft:stone;;23;61;18;NULL +minecraft:stone;;23;61;19;NULL +minecraft:stone;;23;61;20;NULL +minecraft:stone;;23;61;21;NULL +minecraft:stone;;23;61;22;NULL +minecraft:stone;;23;61;23;NULL +minecraft:stone;;23;61;24;NULL +minecraft:stone;;23;61;25;NULL +minecraft:stone;;23;61;26;NULL +minecraft:stone;;23;61;27;NULL +minecraft:stone;;23;61;28;NULL +minecraft:stone_bricks;;23;61;29;NULL +minecraft:stone_bricks;;24;61;3;NULL +minecraft:stone;;24;61;4;NULL +minecraft:stone;;24;61;5;NULL +minecraft:stone;;24;61;6;NULL +minecraft:stone;;24;61;7;NULL +minecraft:stone;;24;61;8;NULL +minecraft:stone;;24;61;9;NULL +minecraft:stone;;24;61;10;NULL +minecraft:stone;;24;61;11;NULL +minecraft:stone;;24;61;12;NULL +minecraft:stone;;24;61;13;NULL +minecraft:stone;;24;61;14;NULL +minecraft:stone;;24;61;15;NULL +minecraft:stone;;24;61;16;NULL +minecraft:stone;;24;61;17;NULL +minecraft:stone;;24;61;18;NULL +minecraft:stone;;24;61;19;NULL +minecraft:stone;;24;61;20;NULL +minecraft:stone;;24;61;21;NULL +minecraft:stone;;24;61;22;NULL +minecraft:stone;;24;61;23;NULL +minecraft:stone;;24;61;24;NULL +minecraft:stone;;24;61;25;NULL +minecraft:stone;;24;61;26;NULL +minecraft:stone;;24;61;27;NULL +minecraft:stone;;24;61;28;NULL +minecraft:stone_bricks;;24;61;29;NULL +minecraft:stone_bricks;;25;61;3;NULL +minecraft:stone;;25;61;4;NULL +minecraft:stone;;25;61;5;NULL +minecraft:stone;;25;61;6;NULL +minecraft:stone;;25;61;7;NULL +minecraft:stone;;25;61;8;NULL +minecraft:stone;;25;61;9;NULL +minecraft:stone;;25;61;10;NULL +minecraft:stone;;25;61;11;NULL +minecraft:stone;;25;61;12;NULL +minecraft:stone;;25;61;13;NULL +minecraft:stone;;25;61;14;NULL +minecraft:stone;;25;61;15;NULL +minecraft:stone;;25;61;16;NULL +minecraft:stone;;25;61;17;NULL +minecraft:stone;;25;61;18;NULL +minecraft:stone;;25;61;19;NULL +minecraft:stone;;25;61;20;NULL +minecraft:stone;;25;61;21;NULL +minecraft:stone;;25;61;22;NULL +minecraft:stone;;25;61;23;NULL +minecraft:stone;;25;61;24;NULL +minecraft:stone;;25;61;25;NULL +minecraft:stone;;25;61;26;NULL +minecraft:stone;;25;61;27;NULL +minecraft:stone;;25;61;28;NULL +minecraft:stone_bricks;;25;61;29;NULL +minecraft:stone_bricks;;26;61;3;NULL +minecraft:stone;;26;61;4;NULL +minecraft:stone;;26;61;5;NULL +minecraft:stone;;26;61;6;NULL +minecraft:stone;;26;61;7;NULL +minecraft:stone;;26;61;8;NULL +minecraft:stone;;26;61;9;NULL +minecraft:stone;;26;61;10;NULL +minecraft:stone;;26;61;11;NULL +minecraft:stone;;26;61;12;NULL +minecraft:stone;;26;61;13;NULL +minecraft:stone;;26;61;14;NULL +minecraft:stone;;26;61;15;NULL +minecraft:stone;;26;61;16;NULL +minecraft:stone;;26;61;17;NULL +minecraft:stone;;26;61;18;NULL +minecraft:stone;;26;61;19;NULL +minecraft:stone;;26;61;20;NULL +minecraft:stone;;26;61;21;NULL +minecraft:stone;;26;61;22;NULL +minecraft:stone;;26;61;23;NULL +minecraft:stone;;26;61;24;NULL +minecraft:stone;;26;61;25;NULL +minecraft:stone;;26;61;26;NULL +minecraft:stone;;26;61;27;NULL +minecraft:stone;;26;61;28;NULL +minecraft:stone_bricks;;26;61;29;NULL +minecraft:stone_bricks;;27;61;3;NULL +minecraft:stone;;27;61;4;NULL +minecraft:stone;;27;61;5;NULL +minecraft:stone;;27;61;6;NULL +minecraft:stone;;27;61;7;NULL +minecraft:stone;;27;61;8;NULL +minecraft:stone;;27;61;9;NULL +minecraft:stone;;27;61;10;NULL +minecraft:stone;;27;61;11;NULL +minecraft:stone;;27;61;12;NULL +minecraft:stone;;27;61;13;NULL +minecraft:stone;;27;61;14;NULL +minecraft:stone;;27;61;15;NULL +minecraft:stone;;27;61;16;NULL +minecraft:stone;;27;61;17;NULL +minecraft:stone;;27;61;18;NULL +minecraft:stone;;27;61;19;NULL +minecraft:stone;;27;61;20;NULL +minecraft:stone;;27;61;21;NULL +minecraft:stone;;27;61;22;NULL +minecraft:stone;;27;61;23;NULL +minecraft:stone;;27;61;24;NULL +minecraft:stone;;27;61;25;NULL +minecraft:stone;;27;61;26;NULL +minecraft:stone;;27;61;27;NULL +minecraft:stone;;27;61;28;NULL +minecraft:stone_bricks;;27;61;29;NULL +minecraft:stone_bricks;;28;61;3;NULL +minecraft:stone;;28;61;4;NULL +minecraft:stone;;28;61;5;NULL +minecraft:stone;;28;61;6;NULL +minecraft:stone;;28;61;7;NULL +minecraft:stone;;28;61;8;NULL +minecraft:stone;;28;61;9;NULL +minecraft:stone;;28;61;10;NULL +minecraft:stone;;28;61;11;NULL +minecraft:stone;;28;61;12;NULL +minecraft:stone;;28;61;13;NULL +minecraft:stone;;28;61;14;NULL +minecraft:stone;;28;61;15;NULL +minecraft:stone;;28;61;16;NULL +minecraft:stone;;28;61;17;NULL +minecraft:stone;;28;61;18;NULL +minecraft:stone;;28;61;19;NULL +minecraft:stone;;28;61;20;NULL +minecraft:stone;;28;61;21;NULL +minecraft:stone;;28;61;22;NULL +minecraft:stone;;28;61;23;NULL +minecraft:stone;;28;61;24;NULL +minecraft:stone;;28;61;25;NULL +minecraft:stone;;28;61;26;NULL +minecraft:stone;;28;61;27;NULL +minecraft:stone;;28;61;28;NULL +minecraft:stone_bricks;;28;61;29;NULL +minecraft:stone_bricks;;29;61;3;NULL +minecraft:stone;;29;61;4;NULL +minecraft:stone;;29;61;5;NULL +minecraft:stone;;29;61;6;NULL +minecraft:stone;;29;61;7;NULL +minecraft:stone;;29;61;8;NULL +minecraft:stone;;29;61;9;NULL +minecraft:stone;;29;61;10;NULL +minecraft:stone;;29;61;11;NULL +minecraft:stone;;29;61;12;NULL +minecraft:stone;;29;61;13;NULL +minecraft:stone;;29;61;14;NULL +minecraft:stone;;29;61;15;NULL +minecraft:stone;;29;61;16;NULL +minecraft:stone;;29;61;17;NULL +minecraft:stone;;29;61;18;NULL +minecraft:stone;;29;61;19;NULL +minecraft:stone;;29;61;20;NULL +minecraft:stone;;29;61;21;NULL +minecraft:stone;;29;61;22;NULL +minecraft:stone;;29;61;23;NULL +minecraft:stone;;29;61;24;NULL +minecraft:stone;;29;61;25;NULL +minecraft:stone;;29;61;26;NULL +minecraft:stone;;29;61;27;NULL +minecraft:stone;;29;61;28;NULL +minecraft:stone_bricks;;29;61;29;NULL +minecraft:stone_bricks;;30;61;3;NULL +minecraft:stone;;30;61;4;NULL +minecraft:stone;;30;61;5;NULL +minecraft:stone;;30;61;6;NULL +minecraft:stone;;30;61;7;NULL +minecraft:stone;;30;61;8;NULL +minecraft:stone;;30;61;9;NULL +minecraft:stone;;30;61;10;NULL +minecraft:stone;;30;61;11;NULL +minecraft:stone;;30;61;12;NULL +minecraft:stone;;30;61;13;NULL +minecraft:stone;;30;61;14;NULL +minecraft:stone;;30;61;15;NULL +minecraft:stone;;30;61;16;NULL +minecraft:stone;;30;61;17;NULL +minecraft:stone;;30;61;18;NULL +minecraft:stone;;30;61;19;NULL +minecraft:stone;;30;61;20;NULL +minecraft:stone;;30;61;21;NULL +minecraft:stone;;30;61;22;NULL +minecraft:stone;;30;61;23;NULL +minecraft:stone;;30;61;24;NULL +minecraft:stone;;30;61;25;NULL +minecraft:stone;;30;61;26;NULL +minecraft:stone;;30;61;27;NULL +minecraft:stone;;30;61;28;NULL +minecraft:stone_bricks;;30;61;29;NULL +minecraft:stone_bricks;;31;61;3;NULL +minecraft:stone;;31;61;4;NULL +minecraft:stone;;31;61;5;NULL +minecraft:stone;;31;61;6;NULL +minecraft:stone;;31;61;7;NULL +minecraft:stone;;31;61;8;NULL +minecraft:stone;;31;61;9;NULL +minecraft:stone;;31;61;10;NULL +minecraft:stone;;31;61;11;NULL +minecraft:stone;;31;61;12;NULL +minecraft:stone;;31;61;13;NULL +minecraft:stone;;31;61;14;NULL +minecraft:stone;;31;61;15;NULL +minecraft:stone;;31;61;16;NULL +minecraft:stone;;31;61;17;NULL +minecraft:stone;;31;61;18;NULL +minecraft:stone;;31;61;19;NULL +minecraft:stone;;31;61;20;NULL +minecraft:stone;;31;61;21;NULL +minecraft:stone;;31;61;22;NULL +minecraft:stone;;31;61;23;NULL +minecraft:stone;;31;61;24;NULL +minecraft:stone;;31;61;25;NULL +minecraft:stone;;31;61;26;NULL +minecraft:stone;;31;61;27;NULL +minecraft:stone;;31;61;28;NULL +minecraft:stone_bricks;;31;61;29;NULL +minecraft:stone_bricks;;32;61;3;NULL +minecraft:stone;;32;61;4;NULL +minecraft:stone;;32;61;5;NULL +minecraft:stone;;32;61;6;NULL +minecraft:stone;;32;61;7;NULL +minecraft:stone;;32;61;8;NULL +minecraft:stone;;32;61;9;NULL +minecraft:stone;;32;61;10;NULL +minecraft:stone;;32;61;11;NULL +minecraft:stone;;32;61;12;NULL +minecraft:stone;;32;61;13;NULL +minecraft:stone;;32;61;14;NULL +minecraft:stone;;32;61;15;NULL +minecraft:stone;;32;61;16;NULL +minecraft:stone;;32;61;17;NULL +minecraft:stone;;32;61;18;NULL +minecraft:stone;;32;61;19;NULL +minecraft:stone;;32;61;20;NULL +minecraft:stone;;32;61;21;NULL +minecraft:stone;;32;61;22;NULL +minecraft:stone;;32;61;23;NULL +minecraft:stone;;32;61;24;NULL +minecraft:stone;;32;61;25;NULL +minecraft:stone;;32;61;26;NULL +minecraft:stone;;32;61;27;NULL +minecraft:stone;;32;61;28;NULL +minecraft:stone_bricks;;32;61;29;NULL +minecraft:stone_bricks;;33;61;3;NULL +minecraft:stone;;33;61;4;NULL +minecraft:stone;;33;61;5;NULL +minecraft:stone;;33;61;6;NULL +minecraft:stone;;33;61;7;NULL +minecraft:stone;;33;61;8;NULL +minecraft:stone;;33;61;9;NULL +minecraft:stone;;33;61;10;NULL +minecraft:stone;;33;61;11;NULL +minecraft:stone;;33;61;12;NULL +minecraft:stone;;33;61;13;NULL +minecraft:stone;;33;61;14;NULL +minecraft:stone;;33;61;15;NULL +minecraft:stone;;33;61;16;NULL +minecraft:stone;;33;61;17;NULL +minecraft:stone;;33;61;18;NULL +minecraft:stone;;33;61;19;NULL +minecraft:stone;;33;61;20;NULL +minecraft:stone;;33;61;21;NULL +minecraft:stone;;33;61;22;NULL +minecraft:stone;;33;61;23;NULL +minecraft:stone;;33;61;24;NULL +minecraft:stone;;33;61;25;NULL +minecraft:stone;;33;61;26;NULL +minecraft:stone;;33;61;27;NULL +minecraft:stone;;33;61;28;NULL +minecraft:stone_bricks;;33;61;29;NULL +minecraft:stone_bricks;;34;61;3;NULL +minecraft:stone;;34;61;4;NULL +minecraft:stone;;34;61;5;NULL +minecraft:stone;;34;61;6;NULL +minecraft:stone;;34;61;7;NULL +minecraft:stone;;34;61;8;NULL +minecraft:stone;;34;61;9;NULL +minecraft:stone;;34;61;10;NULL +minecraft:stone;;34;61;11;NULL +minecraft:stone;;34;61;12;NULL +minecraft:stone;;34;61;13;NULL +minecraft:stone;;34;61;14;NULL +minecraft:stone;;34;61;15;NULL +minecraft:stone;;34;61;16;NULL +minecraft:stone;;34;61;17;NULL +minecraft:stone;;34;61;18;NULL +minecraft:stone;;34;61;19;NULL +minecraft:stone;;34;61;20;NULL +minecraft:stone;;34;61;21;NULL +minecraft:stone;;34;61;22;NULL +minecraft:stone;;34;61;23;NULL +minecraft:stone;;34;61;24;NULL +minecraft:stone;;34;61;25;NULL +minecraft:stone;;34;61;26;NULL +minecraft:stone;;34;61;27;NULL +minecraft:stone;;34;61;28;NULL +minecraft:stone_bricks;;34;61;29;NULL +minecraft:stone_bricks;;35;61;3;NULL +minecraft:stone;;35;61;4;NULL +minecraft:stone;;35;61;5;NULL +minecraft:stone;;35;61;6;NULL +minecraft:stone;;35;61;7;NULL +minecraft:stone;;35;61;8;NULL +minecraft:stone;;35;61;9;NULL +minecraft:stone;;35;61;10;NULL +minecraft:stone;;35;61;11;NULL +minecraft:stone;;35;61;12;NULL +minecraft:stone;;35;61;13;NULL +minecraft:stone;;35;61;14;NULL +minecraft:stone;;35;61;15;NULL +minecraft:stone;;35;61;16;NULL +minecraft:stone;;35;61;17;NULL +minecraft:stone;;35;61;18;NULL +minecraft:stone;;35;61;19;NULL +minecraft:stone;;35;61;20;NULL +minecraft:stone;;35;61;21;NULL +minecraft:stone;;35;61;22;NULL +minecraft:stone;;35;61;23;NULL +minecraft:stone;;35;61;24;NULL +minecraft:stone;;35;61;25;NULL +minecraft:stone;;35;61;26;NULL +minecraft:stone;;35;61;27;NULL +minecraft:stone;;35;61;28;NULL +minecraft:stone_bricks;;35;61;29;NULL +minecraft:stone_bricks;;36;61;3;NULL +minecraft:stone;;36;61;4;NULL +minecraft:stone;;36;61;5;NULL +minecraft:stone;;36;61;6;NULL +minecraft:stone;;36;61;7;NULL +minecraft:stone;;36;61;8;NULL +minecraft:stone;;36;61;9;NULL +minecraft:stone;;36;61;10;NULL +minecraft:stone;;36;61;11;NULL +minecraft:stone;;36;61;12;NULL +minecraft:stone;;36;61;13;NULL +minecraft:stone;;36;61;14;NULL +minecraft:stone;;36;61;15;NULL +minecraft:stone;;36;61;16;NULL +minecraft:stone;;36;61;17;NULL +minecraft:stone;;36;61;18;NULL +minecraft:stone;;36;61;19;NULL +minecraft:stone;;36;61;20;NULL +minecraft:stone;;36;61;21;NULL +minecraft:stone;;36;61;22;NULL +minecraft:stone;;36;61;23;NULL +minecraft:stone;;36;61;24;NULL +minecraft:stone;;36;61;25;NULL +minecraft:stone;;36;61;26;NULL +minecraft:stone;;36;61;27;NULL +minecraft:stone;;36;61;28;NULL +minecraft:stone_bricks;;36;61;29;NULL +minecraft:stone_bricks;;37;61;3;NULL +minecraft:stone;;37;61;4;NULL +minecraft:stone;;37;61;5;NULL +minecraft:stone;;37;61;6;NULL +minecraft:stone;;37;61;7;NULL +minecraft:stone;;37;61;8;NULL +minecraft:stone;;37;61;9;NULL +minecraft:stone;;37;61;10;NULL +minecraft:stone;;37;61;11;NULL +minecraft:stone;;37;61;12;NULL +minecraft:stone;;37;61;13;NULL +minecraft:stone;;37;61;14;NULL +minecraft:stone;;37;61;15;NULL +minecraft:stone;;37;61;16;NULL +minecraft:stone;;37;61;17;NULL +minecraft:stone;;37;61;18;NULL +minecraft:stone;;37;61;19;NULL +minecraft:stone;;37;61;20;NULL +minecraft:stone;;37;61;21;NULL +minecraft:stone;;37;61;22;NULL +minecraft:stone;;37;61;23;NULL +minecraft:stone;;37;61;24;NULL +minecraft:stone;;37;61;25;NULL +minecraft:stone;;37;61;26;NULL +minecraft:stone;;37;61;27;NULL +minecraft:stone;;37;61;28;NULL +minecraft:stone_bricks;;37;61;29;NULL +minecraft:stone_bricks;;38;61;3;NULL +minecraft:stone;;38;61;4;NULL +minecraft:stone;;38;61;5;NULL +minecraft:stone;;38;61;6;NULL +minecraft:stone;;38;61;7;NULL +minecraft:stone;;38;61;8;NULL +minecraft:stone;;38;61;9;NULL +minecraft:stone;;38;61;10;NULL +minecraft:stone;;38;61;11;NULL +minecraft:stone;;38;61;12;NULL +minecraft:stone;;38;61;13;NULL +minecraft:stone;;38;61;14;NULL +minecraft:stone;;38;61;15;NULL +minecraft:stone;;38;61;16;NULL +minecraft:stone;;38;61;17;NULL +minecraft:stone;;38;61;18;NULL +minecraft:stone;;38;61;19;NULL +minecraft:stone;;38;61;20;NULL +minecraft:stone;;38;61;21;NULL +minecraft:stone;;38;61;22;NULL +minecraft:stone;;38;61;23;NULL +minecraft:stone;;38;61;24;NULL +minecraft:stone;;38;61;25;NULL +minecraft:stone;;38;61;26;NULL +minecraft:stone;;38;61;27;NULL +minecraft:stone;;38;61;28;NULL +minecraft:stone_bricks;;38;61;29;NULL +minecraft:stone_bricks;;39;61;3;NULL +minecraft:stone;;39;61;4;NULL +minecraft:stone;;39;61;5;NULL +minecraft:stone;;39;61;6;NULL +minecraft:stone;;39;61;7;NULL +minecraft:stone;;39;61;8;NULL +minecraft:stone;;39;61;9;NULL +minecraft:stone;;39;61;10;NULL +minecraft:stone;;39;61;11;NULL +minecraft:stone;;39;61;12;NULL +minecraft:stone;;39;61;13;NULL +minecraft:stone;;39;61;14;NULL +minecraft:stone;;39;61;15;NULL +minecraft:stone;;39;61;16;NULL +minecraft:stone;;39;61;17;NULL +minecraft:stone;;39;61;18;NULL +minecraft:stone;;39;61;19;NULL +minecraft:stone;;39;61;20;NULL +minecraft:stone;;39;61;21;NULL +minecraft:stone;;39;61;22;NULL +minecraft:stone;;39;61;23;NULL +minecraft:stone;;39;61;24;NULL +minecraft:stone;;39;61;25;NULL +minecraft:stone;;39;61;26;NULL +minecraft:stone;;39;61;27;NULL +minecraft:stone;;39;61;28;NULL +minecraft:stone_bricks;;39;61;29;NULL +minecraft:stone_bricks;;40;61;3;NULL +minecraft:stone;;40;61;4;NULL +minecraft:stone;;40;61;5;NULL +minecraft:stone;;40;61;6;NULL +minecraft:stone;;40;61;7;NULL +minecraft:stone;;40;61;8;NULL +minecraft:stone;;40;61;9;NULL +minecraft:stone;;40;61;10;NULL +minecraft:stone;;40;61;11;NULL +minecraft:stone;;40;61;12;NULL +minecraft:stone;;40;61;13;NULL +minecraft:stone;;40;61;14;NULL +minecraft:stone;;40;61;15;NULL +minecraft:stone;;40;61;16;NULL +minecraft:stone;;40;61;17;NULL +minecraft:stone;;40;61;18;NULL +minecraft:stone;;40;61;19;NULL +minecraft:stone;;40;61;20;NULL +minecraft:stone;;40;61;21;NULL +minecraft:stone;;40;61;22;NULL +minecraft:stone;;40;61;23;NULL +minecraft:stone;;40;61;24;NULL +minecraft:stone;;40;61;25;NULL +minecraft:stone;;40;61;26;NULL +minecraft:stone;;40;61;27;NULL +minecraft:stone;;40;61;28;NULL +minecraft:stone_bricks;;40;61;29;NULL +minecraft:stone_bricks;;41;61;3;NULL +minecraft:stone;;41;61;4;NULL +minecraft:stone;;41;61;5;NULL +minecraft:stone;;41;61;6;NULL +minecraft:stone;;41;61;7;NULL +minecraft:stone;;41;61;8;NULL +minecraft:stone;;41;61;9;NULL +minecraft:stone;;41;61;10;NULL +minecraft:stone;;41;61;11;NULL +minecraft:stone;;41;61;12;NULL +minecraft:stone;;41;61;13;NULL +minecraft:stone;;41;61;14;NULL +minecraft:stone;;41;61;15;NULL +minecraft:stone;;41;61;16;NULL +minecraft:stone;;41;61;17;NULL +minecraft:stone;;41;61;18;NULL +minecraft:stone;;41;61;19;NULL +minecraft:stone;;41;61;20;NULL +minecraft:stone;;41;61;21;NULL +minecraft:stone;;41;61;22;NULL +minecraft:stone;;41;61;23;NULL +minecraft:stone;;41;61;24;NULL +minecraft:stone;;41;61;25;NULL +minecraft:stone;;41;61;26;NULL +minecraft:stone;;41;61;27;NULL +minecraft:stone;;41;61;28;NULL +minecraft:stone_bricks;;41;61;29;NULL +minecraft:stone_bricks;;42;61;3;NULL +minecraft:stone;;42;61;4;NULL +minecraft:stone;;42;61;5;NULL +minecraft:stone;;42;61;6;NULL +minecraft:stone;;42;61;7;NULL +minecraft:stone;;42;61;8;NULL +minecraft:stone;;42;61;9;NULL +minecraft:stone;;42;61;10;NULL +minecraft:stone;;42;61;11;NULL +minecraft:stone;;42;61;12;NULL +minecraft:stone;;42;61;13;NULL +minecraft:stone;;42;61;14;NULL +minecraft:stone;;42;61;15;NULL +minecraft:stone;;42;61;16;NULL +minecraft:stone;;42;61;17;NULL +minecraft:stone;;42;61;18;NULL +minecraft:stone;;42;61;19;NULL +minecraft:stone;;42;61;20;NULL +minecraft:stone;;42;61;21;NULL +minecraft:stone;;42;61;22;NULL +minecraft:stone;;42;61;23;NULL +minecraft:stone;;42;61;24;NULL +minecraft:stone;;42;61;25;NULL +minecraft:stone;;42;61;26;NULL +minecraft:stone;;42;61;27;NULL +minecraft:stone;;42;61;28;NULL +minecraft:stone_bricks;;42;61;29;NULL +minecraft:stone_bricks;;43;61;3;NULL +minecraft:stone;;43;61;4;NULL +minecraft:stone;;43;61;5;NULL +minecraft:stone;;43;61;6;NULL +minecraft:stone;;43;61;7;NULL +minecraft:stone;;43;61;8;NULL +minecraft:stone;;43;61;9;NULL +minecraft:stone;;43;61;10;NULL +minecraft:stone;;43;61;11;NULL +minecraft:stone;;43;61;12;NULL +minecraft:stone;;43;61;13;NULL +minecraft:stone;;43;61;14;NULL +minecraft:stone;;43;61;15;NULL +minecraft:stone;;43;61;16;NULL +minecraft:stone;;43;61;17;NULL +minecraft:stone;;43;61;18;NULL +minecraft:stone;;43;61;19;NULL +minecraft:stone;;43;61;20;NULL +minecraft:stone;;43;61;21;NULL +minecraft:stone;;43;61;22;NULL +minecraft:stone;;43;61;23;NULL +minecraft:stone;;43;61;24;NULL +minecraft:stone;;43;61;25;NULL +minecraft:stone;;43;61;26;NULL +minecraft:stone;;43;61;27;NULL +minecraft:stone;;43;61;28;NULL +minecraft:stone_bricks;;43;61;29;NULL +minecraft:stone_bricks;;44;61;3;NULL +minecraft:stone;;44;61;4;NULL +minecraft:stone;;44;61;5;NULL +minecraft:stone;;44;61;6;NULL +minecraft:stone;;44;61;7;NULL +minecraft:stone;;44;61;8;NULL +minecraft:stone;;44;61;9;NULL +minecraft:stone;;44;61;10;NULL +minecraft:stone;;44;61;11;NULL +minecraft:stone;;44;61;12;NULL +minecraft:stone;;44;61;13;NULL +minecraft:stone;;44;61;14;NULL +minecraft:stone;;44;61;15;NULL +minecraft:stone;;44;61;16;NULL +minecraft:stone;;44;61;17;NULL +minecraft:stone;;44;61;18;NULL +minecraft:stone;;44;61;19;NULL +minecraft:stone;;44;61;20;NULL +minecraft:stone;;44;61;21;NULL +minecraft:stone;;44;61;22;NULL +minecraft:stone;;44;61;23;NULL +minecraft:stone;;44;61;24;NULL +minecraft:stone;;44;61;25;NULL +minecraft:stone;;44;61;26;NULL +minecraft:stone;;44;61;27;NULL +minecraft:stone;;44;61;28;NULL +minecraft:stone_bricks;;44;61;29;NULL +minecraft:stone_bricks;;45;61;3;NULL +minecraft:stone_bricks;;45;61;4;NULL +minecraft:stone_bricks;;45;61;5;NULL +minecraft:stone_bricks;;45;61;6;NULL +minecraft:stone_bricks;;45;61;7;NULL +minecraft:stone_bricks;;45;61;8;NULL +minecraft:stone_bricks;;45;61;9;NULL +minecraft:stone_bricks;;45;61;10;NULL +minecraft:stone_bricks;;45;61;11;NULL +minecraft:stone_bricks;;45;61;12;NULL +minecraft:stone_bricks;;45;61;13;NULL +minecraft:stone_bricks;;45;61;14;NULL +minecraft:stone_bricks;;45;61;15;NULL +minecraft:stone_bricks;;45;61;16;NULL +minecraft:stone_bricks;;45;61;17;NULL +minecraft:stone_bricks;;45;61;18;NULL +minecraft:stone_bricks;;45;61;19;NULL +minecraft:stone_bricks;;45;61;20;NULL +minecraft:stone_bricks;;45;61;21;NULL +minecraft:stone_bricks;;45;61;22;NULL +minecraft:stone_bricks;;45;61;23;NULL +minecraft:stone_bricks;;45;61;24;NULL +minecraft:stone_bricks;;45;61;25;NULL +minecraft:stone_bricks;;45;61;26;NULL +minecraft:stone_bricks;;45;61;27;NULL +minecraft:stone_bricks;;45;61;28;NULL +minecraft:stone_bricks;;45;61;29;NULL +minecraft:sign;rotation=6;3;62;3; +minecraft:sign;rotation=10;45;62;3; +minecraft:sign;rotation=2;3;62;29; +minecraft:sign;rotation=14;45;62;29; +minecraft:stone_bricks;;33;62;6;NULL +minecraft:stone_bricks;;33;62;7;NULL +minecraft:stone_bricks;;33;62;8;NULL +minecraft:stone_bricks;;33;62;9;NULL +minecraft:stone_bricks;;33;62;10;NULL +minecraft:stone_bricks;;33;62;11;NULL +minecraft:stone_bricks;;33;62;12;NULL +minecraft:stone_bricks;;33;62;13;NULL +minecraft:stone_bricks;;33;62;14;NULL +minecraft:stone_bricks;;34;62;6;NULL +minecraft:stone;;34;62;7;NULL +minecraft:stone;;34;62;8;NULL +minecraft:stone;;34;62;9;NULL +minecraft:stone;;34;62;10;NULL +minecraft:stone;;34;62;11;NULL +minecraft:stone;;34;62;12;NULL +minecraft:stone;;34;62;13;NULL +minecraft:stone_bricks;;34;62;14;NULL +minecraft:stone_bricks;;35;62;6;NULL +minecraft:stone;;35;62;7;NULL +minecraft:stone;;35;62;8;NULL +minecraft:stone;;35;62;9;NULL +minecraft:stone;;35;62;10;NULL +minecraft:stone;;35;62;11;NULL +minecraft:stone;;35;62;12;NULL +minecraft:stone;;35;62;13;NULL +minecraft:stone_bricks;;35;62;14;NULL +minecraft:stone_bricks;;36;62;6;NULL +minecraft:stone;;36;62;7;NULL +minecraft:stone;;36;62;8;NULL +minecraft:stone;;36;62;9;NULL +minecraft:stone;;36;62;10;NULL +minecraft:stone;;36;62;11;NULL +minecraft:stone;;36;62;12;NULL +minecraft:stone;;36;62;13;NULL +minecraft:stone_bricks;;36;62;14;NULL +minecraft:stone_bricks;;37;62;6;NULL +minecraft:stone;;37;62;7;NULL +minecraft:stone;;37;62;8;NULL +minecraft:stone;;37;62;9;NULL +minecraft:stone;;37;62;10;NULL +minecraft:stone;;37;62;11;NULL +minecraft:stone;;37;62;12;NULL +minecraft:stone;;37;62;13;NULL +minecraft:stone_bricks;;37;62;14;NULL +minecraft:stone_bricks;;38;62;6;NULL +minecraft:stone;;38;62;7;NULL +minecraft:stone;;38;62;8;NULL +minecraft:stone;;38;62;9;NULL +minecraft:stone;;38;62;10;NULL +minecraft:stone;;38;62;11;NULL +minecraft:stone;;38;62;12;NULL +minecraft:stone;;38;62;13;NULL +minecraft:stone_bricks;;38;62;14;NULL +minecraft:stone_bricks;;39;62;6;NULL +minecraft:stone;;39;62;7;NULL +minecraft:stone;;39;62;8;NULL +minecraft:stone;;39;62;9;NULL +minecraft:stone;;39;62;10;NULL +minecraft:stone;;39;62;11;NULL +minecraft:stone;;39;62;12;NULL +minecraft:stone;;39;62;13;NULL +minecraft:stone_bricks;;39;62;14;NULL +minecraft:stone_bricks;;40;62;6;NULL +minecraft:stone;;40;62;7;NULL +minecraft:stone;;40;62;8;NULL +minecraft:stone;;40;62;9;NULL +minecraft:stone;;40;62;10;NULL +minecraft:stone;;40;62;11;NULL +minecraft:stone;;40;62;12;NULL +minecraft:stone;;40;62;13;NULL +minecraft:stone_bricks;;40;62;14;NULL +minecraft:stone_bricks;;41;62;6;NULL +minecraft:stone_bricks;;41;62;7;NULL +minecraft:stone_bricks;;41;62;8;NULL +minecraft:stone_bricks;;41;62;9;NULL +minecraft:stone_bricks;;41;62;10;NULL +minecraft:stone_bricks;;41;62;11;NULL +minecraft:stone_bricks;;41;62;12;NULL +minecraft:stone_bricks;;41;62;13;NULL +minecraft:stone_bricks;;41;62;14;NULL +minecraft:sign;rotation=6;33;63;6;unnamed package +minecraft:sign;rotation=10;41;63;6;unnamed package +minecraft:sign;rotation=2;33;63;14;unnamed package +minecraft:sign;rotation=14;41;63;14;unnamed package +minecraft:stone_bricks;;6;62;6;NULL +minecraft:stone_bricks;;6;62;7;NULL +minecraft:stone_bricks;;6;62;8;NULL +minecraft:stone_bricks;;6;62;9;NULL +minecraft:stone_bricks;;6;62;10;NULL +minecraft:stone_bricks;;6;62;11;NULL +minecraft:stone_bricks;;6;62;12;NULL +minecraft:stone_bricks;;6;62;13;NULL +minecraft:stone_bricks;;6;62;14;NULL +minecraft:stone_bricks;;6;62;15;NULL +minecraft:stone_bricks;;6;62;16;NULL +minecraft:stone_bricks;;6;62;17;NULL +minecraft:stone_bricks;;6;62;18;NULL +minecraft:stone_bricks;;6;62;19;NULL +minecraft:stone_bricks;;6;62;20;NULL +minecraft:stone_bricks;;6;62;21;NULL +minecraft:stone_bricks;;6;62;22;NULL +minecraft:stone_bricks;;6;62;23;NULL +minecraft:stone_bricks;;6;62;24;NULL +minecraft:stone_bricks;;6;62;25;NULL +minecraft:stone_bricks;;6;62;26;NULL +minecraft:stone_bricks;;7;62;6;NULL +minecraft:stone;;7;62;7;NULL +minecraft:stone;;7;62;8;NULL +minecraft:stone;;7;62;9;NULL +minecraft:stone;;7;62;10;NULL +minecraft:stone;;7;62;11;NULL +minecraft:stone;;7;62;12;NULL +minecraft:stone;;7;62;13;NULL +minecraft:stone;;7;62;14;NULL +minecraft:stone;;7;62;15;NULL +minecraft:stone;;7;62;16;NULL +minecraft:stone;;7;62;17;NULL +minecraft:stone;;7;62;18;NULL +minecraft:stone;;7;62;19;NULL +minecraft:stone;;7;62;20;NULL +minecraft:stone;;7;62;21;NULL +minecraft:stone;;7;62;22;NULL +minecraft:stone;;7;62;23;NULL +minecraft:stone;;7;62;24;NULL +minecraft:stone;;7;62;25;NULL +minecraft:stone_bricks;;7;62;26;NULL +minecraft:stone_bricks;;8;62;6;NULL +minecraft:stone;;8;62;7;NULL +minecraft:stone;;8;62;8;NULL +minecraft:stone;;8;62;9;NULL +minecraft:stone;;8;62;10;NULL +minecraft:stone;;8;62;11;NULL +minecraft:stone;;8;62;12;NULL +minecraft:stone;;8;62;13;NULL +minecraft:stone;;8;62;14;NULL +minecraft:stone;;8;62;15;NULL +minecraft:stone;;8;62;16;NULL +minecraft:stone;;8;62;17;NULL +minecraft:stone;;8;62;18;NULL +minecraft:stone;;8;62;19;NULL +minecraft:stone;;8;62;20;NULL +minecraft:stone;;8;62;21;NULL +minecraft:stone;;8;62;22;NULL +minecraft:stone;;8;62;23;NULL +minecraft:stone;;8;62;24;NULL +minecraft:stone;;8;62;25;NULL +minecraft:stone_bricks;;8;62;26;NULL +minecraft:stone_bricks;;9;62;6;NULL +minecraft:stone;;9;62;7;NULL +minecraft:stone;;9;62;8;NULL +minecraft:stone;;9;62;9;NULL +minecraft:stone;;9;62;10;NULL +minecraft:stone;;9;62;11;NULL +minecraft:stone;;9;62;12;NULL +minecraft:stone;;9;62;13;NULL +minecraft:stone;;9;62;14;NULL +minecraft:stone;;9;62;15;NULL +minecraft:stone;;9;62;16;NULL +minecraft:stone;;9;62;17;NULL +minecraft:stone;;9;62;18;NULL +minecraft:stone;;9;62;19;NULL +minecraft:stone;;9;62;20;NULL +minecraft:stone;;9;62;21;NULL +minecraft:stone;;9;62;22;NULL +minecraft:stone;;9;62;23;NULL +minecraft:stone;;9;62;24;NULL +minecraft:stone;;9;62;25;NULL +minecraft:stone_bricks;;9;62;26;NULL +minecraft:stone_bricks;;10;62;6;NULL +minecraft:stone;;10;62;7;NULL +minecraft:stone;;10;62;8;NULL +minecraft:stone;;10;62;9;NULL +minecraft:stone;;10;62;10;NULL +minecraft:stone;;10;62;11;NULL +minecraft:stone;;10;62;12;NULL +minecraft:stone;;10;62;13;NULL +minecraft:stone;;10;62;14;NULL +minecraft:stone;;10;62;15;NULL +minecraft:stone;;10;62;16;NULL +minecraft:stone;;10;62;17;NULL +minecraft:stone;;10;62;18;NULL +minecraft:stone;;10;62;19;NULL +minecraft:stone;;10;62;20;NULL +minecraft:stone;;10;62;21;NULL +minecraft:stone;;10;62;22;NULL +minecraft:stone;;10;62;23;NULL +minecraft:stone;;10;62;24;NULL +minecraft:stone;;10;62;25;NULL +minecraft:stone_bricks;;10;62;26;NULL +minecraft:stone_bricks;;11;62;6;NULL +minecraft:stone;;11;62;7;NULL +minecraft:stone;;11;62;8;NULL +minecraft:stone;;11;62;9;NULL +minecraft:stone;;11;62;10;NULL +minecraft:stone;;11;62;11;NULL +minecraft:stone;;11;62;12;NULL +minecraft:stone;;11;62;13;NULL +minecraft:stone;;11;62;14;NULL +minecraft:stone;;11;62;15;NULL +minecraft:stone;;11;62;16;NULL +minecraft:stone;;11;62;17;NULL +minecraft:stone;;11;62;18;NULL +minecraft:stone;;11;62;19;NULL +minecraft:stone;;11;62;20;NULL +minecraft:stone;;11;62;21;NULL +minecraft:stone;;11;62;22;NULL +minecraft:stone;;11;62;23;NULL +minecraft:stone;;11;62;24;NULL +minecraft:stone;;11;62;25;NULL +minecraft:stone_bricks;;11;62;26;NULL +minecraft:stone_bricks;;12;62;6;NULL +minecraft:stone;;12;62;7;NULL +minecraft:stone;;12;62;8;NULL +minecraft:stone;;12;62;9;NULL +minecraft:stone;;12;62;10;NULL +minecraft:stone;;12;62;11;NULL +minecraft:stone;;12;62;12;NULL +minecraft:stone;;12;62;13;NULL +minecraft:stone;;12;62;14;NULL +minecraft:stone;;12;62;15;NULL +minecraft:stone;;12;62;16;NULL +minecraft:stone;;12;62;17;NULL +minecraft:stone;;12;62;18;NULL +minecraft:stone;;12;62;19;NULL +minecraft:stone;;12;62;20;NULL +minecraft:stone;;12;62;21;NULL +minecraft:stone;;12;62;22;NULL +minecraft:stone;;12;62;23;NULL +minecraft:stone;;12;62;24;NULL +minecraft:stone;;12;62;25;NULL +minecraft:stone_bricks;;12;62;26;NULL +minecraft:stone_bricks;;13;62;6;NULL +minecraft:stone;;13;62;7;NULL +minecraft:stone;;13;62;8;NULL +minecraft:stone;;13;62;9;NULL +minecraft:stone;;13;62;10;NULL +minecraft:stone;;13;62;11;NULL +minecraft:stone;;13;62;12;NULL +minecraft:stone;;13;62;13;NULL +minecraft:stone;;13;62;14;NULL +minecraft:stone;;13;62;15;NULL +minecraft:stone;;13;62;16;NULL +minecraft:stone;;13;62;17;NULL +minecraft:stone;;13;62;18;NULL +minecraft:stone;;13;62;19;NULL +minecraft:stone;;13;62;20;NULL +minecraft:stone;;13;62;21;NULL +minecraft:stone;;13;62;22;NULL +minecraft:stone;;13;62;23;NULL +minecraft:stone;;13;62;24;NULL +minecraft:stone;;13;62;25;NULL +minecraft:stone_bricks;;13;62;26;NULL +minecraft:stone_bricks;;14;62;6;NULL +minecraft:stone;;14;62;7;NULL +minecraft:stone;;14;62;8;NULL +minecraft:stone;;14;62;9;NULL +minecraft:stone;;14;62;10;NULL +minecraft:stone;;14;62;11;NULL +minecraft:stone;;14;62;12;NULL +minecraft:stone;;14;62;13;NULL +minecraft:stone;;14;62;14;NULL +minecraft:stone;;14;62;15;NULL +minecraft:stone;;14;62;16;NULL +minecraft:stone;;14;62;17;NULL +minecraft:stone;;14;62;18;NULL +minecraft:stone;;14;62;19;NULL +minecraft:stone;;14;62;20;NULL +minecraft:stone;;14;62;21;NULL +minecraft:stone;;14;62;22;NULL +minecraft:stone;;14;62;23;NULL +minecraft:stone;;14;62;24;NULL +minecraft:stone;;14;62;25;NULL +minecraft:stone_bricks;;14;62;26;NULL +minecraft:stone_bricks;;15;62;6;NULL +minecraft:stone;;15;62;7;NULL +minecraft:stone;;15;62;8;NULL +minecraft:stone;;15;62;9;NULL +minecraft:stone;;15;62;10;NULL +minecraft:stone;;15;62;11;NULL +minecraft:stone;;15;62;12;NULL +minecraft:stone;;15;62;13;NULL +minecraft:stone;;15;62;14;NULL +minecraft:stone;;15;62;15;NULL +minecraft:stone;;15;62;16;NULL +minecraft:stone;;15;62;17;NULL +minecraft:stone;;15;62;18;NULL +minecraft:stone;;15;62;19;NULL +minecraft:stone;;15;62;20;NULL +minecraft:stone;;15;62;21;NULL +minecraft:stone;;15;62;22;NULL +minecraft:stone;;15;62;23;NULL +minecraft:stone;;15;62;24;NULL +minecraft:stone;;15;62;25;NULL +minecraft:stone_bricks;;15;62;26;NULL +minecraft:stone_bricks;;16;62;6;NULL +minecraft:stone;;16;62;7;NULL +minecraft:stone;;16;62;8;NULL +minecraft:stone;;16;62;9;NULL +minecraft:stone;;16;62;10;NULL +minecraft:stone;;16;62;11;NULL +minecraft:stone;;16;62;12;NULL +minecraft:stone;;16;62;13;NULL +minecraft:stone;;16;62;14;NULL +minecraft:stone;;16;62;15;NULL +minecraft:stone;;16;62;16;NULL +minecraft:stone;;16;62;17;NULL +minecraft:stone;;16;62;18;NULL +minecraft:stone;;16;62;19;NULL +minecraft:stone;;16;62;20;NULL +minecraft:stone;;16;62;21;NULL +minecraft:stone;;16;62;22;NULL +minecraft:stone;;16;62;23;NULL +minecraft:stone;;16;62;24;NULL +minecraft:stone;;16;62;25;NULL +minecraft:stone_bricks;;16;62;26;NULL +minecraft:stone_bricks;;17;62;6;NULL +minecraft:stone;;17;62;7;NULL +minecraft:stone;;17;62;8;NULL +minecraft:stone;;17;62;9;NULL +minecraft:stone;;17;62;10;NULL +minecraft:stone;;17;62;11;NULL +minecraft:stone;;17;62;12;NULL +minecraft:stone;;17;62;13;NULL +minecraft:stone;;17;62;14;NULL +minecraft:stone;;17;62;15;NULL +minecraft:stone;;17;62;16;NULL +minecraft:stone;;17;62;17;NULL +minecraft:stone;;17;62;18;NULL +minecraft:stone;;17;62;19;NULL +minecraft:stone;;17;62;20;NULL +minecraft:stone;;17;62;21;NULL +minecraft:stone;;17;62;22;NULL +minecraft:stone;;17;62;23;NULL +minecraft:stone;;17;62;24;NULL +minecraft:stone;;17;62;25;NULL +minecraft:stone_bricks;;17;62;26;NULL +minecraft:stone_bricks;;18;62;6;NULL +minecraft:stone;;18;62;7;NULL +minecraft:stone;;18;62;8;NULL +minecraft:stone;;18;62;9;NULL +minecraft:stone;;18;62;10;NULL +minecraft:stone;;18;62;11;NULL +minecraft:stone;;18;62;12;NULL +minecraft:stone;;18;62;13;NULL +minecraft:stone;;18;62;14;NULL +minecraft:stone;;18;62;15;NULL +minecraft:stone;;18;62;16;NULL +minecraft:stone;;18;62;17;NULL +minecraft:stone;;18;62;18;NULL +minecraft:stone;;18;62;19;NULL +minecraft:stone;;18;62;20;NULL +minecraft:stone;;18;62;21;NULL +minecraft:stone;;18;62;22;NULL +minecraft:stone;;18;62;23;NULL +minecraft:stone;;18;62;24;NULL +minecraft:stone;;18;62;25;NULL +minecraft:stone_bricks;;18;62;26;NULL +minecraft:stone_bricks;;19;62;6;NULL +minecraft:stone;;19;62;7;NULL +minecraft:stone;;19;62;8;NULL +minecraft:stone;;19;62;9;NULL +minecraft:stone;;19;62;10;NULL +minecraft:stone;;19;62;11;NULL +minecraft:stone;;19;62;12;NULL +minecraft:stone;;19;62;13;NULL +minecraft:stone;;19;62;14;NULL +minecraft:stone;;19;62;15;NULL +minecraft:stone;;19;62;16;NULL +minecraft:stone;;19;62;17;NULL +minecraft:stone;;19;62;18;NULL +minecraft:stone;;19;62;19;NULL +minecraft:stone;;19;62;20;NULL +minecraft:stone;;19;62;21;NULL +minecraft:stone;;19;62;22;NULL +minecraft:stone;;19;62;23;NULL +minecraft:stone;;19;62;24;NULL +minecraft:stone;;19;62;25;NULL +minecraft:stone_bricks;;19;62;26;NULL +minecraft:stone_bricks;;20;62;6;NULL +minecraft:stone;;20;62;7;NULL +minecraft:stone;;20;62;8;NULL +minecraft:stone;;20;62;9;NULL +minecraft:stone;;20;62;10;NULL +minecraft:stone;;20;62;11;NULL +minecraft:stone;;20;62;12;NULL +minecraft:stone;;20;62;13;NULL +minecraft:stone;;20;62;14;NULL +minecraft:stone;;20;62;15;NULL +minecraft:stone;;20;62;16;NULL +minecraft:stone;;20;62;17;NULL +minecraft:stone;;20;62;18;NULL +minecraft:stone;;20;62;19;NULL +minecraft:stone;;20;62;20;NULL +minecraft:stone;;20;62;21;NULL +minecraft:stone;;20;62;22;NULL +minecraft:stone;;20;62;23;NULL +minecraft:stone;;20;62;24;NULL +minecraft:stone;;20;62;25;NULL +minecraft:stone_bricks;;20;62;26;NULL +minecraft:stone_bricks;;21;62;6;NULL +minecraft:stone;;21;62;7;NULL +minecraft:stone;;21;62;8;NULL +minecraft:stone;;21;62;9;NULL +minecraft:stone;;21;62;10;NULL +minecraft:stone;;21;62;11;NULL +minecraft:stone;;21;62;12;NULL +minecraft:stone;;21;62;13;NULL +minecraft:stone;;21;62;14;NULL +minecraft:stone;;21;62;15;NULL +minecraft:stone;;21;62;16;NULL +minecraft:stone;;21;62;17;NULL +minecraft:stone;;21;62;18;NULL +minecraft:stone;;21;62;19;NULL +minecraft:stone;;21;62;20;NULL +minecraft:stone;;21;62;21;NULL +minecraft:stone;;21;62;22;NULL +minecraft:stone;;21;62;23;NULL +minecraft:stone;;21;62;24;NULL +minecraft:stone;;21;62;25;NULL +minecraft:stone_bricks;;21;62;26;NULL +minecraft:stone_bricks;;22;62;6;NULL +minecraft:stone;;22;62;7;NULL +minecraft:stone;;22;62;8;NULL +minecraft:stone;;22;62;9;NULL +minecraft:stone;;22;62;10;NULL +minecraft:stone;;22;62;11;NULL +minecraft:stone;;22;62;12;NULL +minecraft:stone;;22;62;13;NULL +minecraft:stone;;22;62;14;NULL +minecraft:stone;;22;62;15;NULL +minecraft:stone;;22;62;16;NULL +minecraft:stone;;22;62;17;NULL +minecraft:stone;;22;62;18;NULL +minecraft:stone;;22;62;19;NULL +minecraft:stone;;22;62;20;NULL +minecraft:stone;;22;62;21;NULL +minecraft:stone;;22;62;22;NULL +minecraft:stone;;22;62;23;NULL +minecraft:stone;;22;62;24;NULL +minecraft:stone;;22;62;25;NULL +minecraft:stone_bricks;;22;62;26;NULL +minecraft:stone_bricks;;23;62;6;NULL +minecraft:stone;;23;62;7;NULL +minecraft:stone;;23;62;8;NULL +minecraft:stone;;23;62;9;NULL +minecraft:stone;;23;62;10;NULL +minecraft:stone;;23;62;11;NULL +minecraft:stone;;23;62;12;NULL +minecraft:stone;;23;62;13;NULL +minecraft:stone;;23;62;14;NULL +minecraft:stone;;23;62;15;NULL +minecraft:stone;;23;62;16;NULL +minecraft:stone;;23;62;17;NULL +minecraft:stone;;23;62;18;NULL +minecraft:stone;;23;62;19;NULL +minecraft:stone;;23;62;20;NULL +minecraft:stone;;23;62;21;NULL +minecraft:stone;;23;62;22;NULL +minecraft:stone;;23;62;23;NULL +minecraft:stone;;23;62;24;NULL +minecraft:stone;;23;62;25;NULL +minecraft:stone_bricks;;23;62;26;NULL +minecraft:stone_bricks;;24;62;6;NULL +minecraft:stone;;24;62;7;NULL +minecraft:stone;;24;62;8;NULL +minecraft:stone;;24;62;9;NULL +minecraft:stone;;24;62;10;NULL +minecraft:stone;;24;62;11;NULL +minecraft:stone;;24;62;12;NULL +minecraft:stone;;24;62;13;NULL +minecraft:stone;;24;62;14;NULL +minecraft:stone;;24;62;15;NULL +minecraft:stone;;24;62;16;NULL +minecraft:stone;;24;62;17;NULL +minecraft:stone;;24;62;18;NULL +minecraft:stone;;24;62;19;NULL +minecraft:stone;;24;62;20;NULL +minecraft:stone;;24;62;21;NULL +minecraft:stone;;24;62;22;NULL +minecraft:stone;;24;62;23;NULL +minecraft:stone;;24;62;24;NULL +minecraft:stone;;24;62;25;NULL +minecraft:stone_bricks;;24;62;26;NULL +minecraft:stone_bricks;;25;62;6;NULL +minecraft:stone;;25;62;7;NULL +minecraft:stone;;25;62;8;NULL +minecraft:stone;;25;62;9;NULL +minecraft:stone;;25;62;10;NULL +minecraft:stone;;25;62;11;NULL +minecraft:stone;;25;62;12;NULL +minecraft:stone;;25;62;13;NULL +minecraft:stone;;25;62;14;NULL +minecraft:stone;;25;62;15;NULL +minecraft:stone;;25;62;16;NULL +minecraft:stone;;25;62;17;NULL +minecraft:stone;;25;62;18;NULL +minecraft:stone;;25;62;19;NULL +minecraft:stone;;25;62;20;NULL +minecraft:stone;;25;62;21;NULL +minecraft:stone;;25;62;22;NULL +minecraft:stone;;25;62;23;NULL +minecraft:stone;;25;62;24;NULL +minecraft:stone;;25;62;25;NULL +minecraft:stone_bricks;;25;62;26;NULL +minecraft:stone_bricks;;26;62;6;NULL +minecraft:stone_bricks;;26;62;7;NULL +minecraft:stone_bricks;;26;62;8;NULL +minecraft:stone_bricks;;26;62;9;NULL +minecraft:stone_bricks;;26;62;10;NULL +minecraft:stone_bricks;;26;62;11;NULL +minecraft:stone_bricks;;26;62;12;NULL +minecraft:stone_bricks;;26;62;13;NULL +minecraft:stone_bricks;;26;62;14;NULL +minecraft:stone_bricks;;26;62;15;NULL +minecraft:stone_bricks;;26;62;16;NULL +minecraft:stone_bricks;;26;62;17;NULL +minecraft:stone_bricks;;26;62;18;NULL +minecraft:stone_bricks;;26;62;19;NULL +minecraft:stone_bricks;;26;62;20;NULL +minecraft:stone_bricks;;26;62;21;NULL +minecraft:stone_bricks;;26;62;22;NULL +minecraft:stone_bricks;;26;62;23;NULL +minecraft:stone_bricks;;26;62;24;NULL +minecraft:stone_bricks;;26;62;25;NULL +minecraft:stone_bricks;;26;62;26;NULL +minecraft:sign;rotation=6;6;63;6;TestProject_Simple1 +minecraft:sign;rotation=10;26;63;6;TestProject_Simple1 +minecraft:sign;rotation=2;6;63;26;TestProject_Simple1 +minecraft:sign;rotation=14;26;63;26;TestProject_Simple1 +minecraft:sandstone;;9;63;9;NULL +minecraft:sandstone;;9;63;10;NULL +minecraft:sandstone;;9;63;11;NULL +minecraft:sandstone;;9;63;12;NULL +minecraft:sandstone;;9;63;13;NULL +minecraft:sandstone;;9;63;14;NULL +minecraft:sandstone;;9;63;15;NULL +minecraft:sandstone;;9;63;16;NULL +minecraft:sandstone;;9;63;17;NULL +minecraft:sandstone;;9;63;18;NULL +minecraft:sandstone;;9;63;19;NULL +minecraft:sandstone;;9;63;20;NULL +minecraft:sandstone;;9;63;21;NULL +minecraft:sandstone;;9;63;22;NULL +minecraft:sandstone;;9;63;23;NULL +minecraft:oak_fence;;9;64;9;NULL +minecraft:oak_fence;;9;64;10;NULL +minecraft:oak_fence;;9;64;11;NULL +minecraft:oak_fence;;9;64;12;NULL +minecraft:oak_fence;;9;64;13;NULL +minecraft:oak_fence;;9;64;14;NULL +minecraft:oak_fence;;9;64;15;NULL +minecraft:oak_fence;;9;64;16;NULL +minecraft:oak_fence;;9;64;17;NULL +minecraft:oak_fence;;9;64;18;NULL +minecraft:oak_fence;;9;64;19;NULL +minecraft:oak_fence;;9;64;20;NULL +minecraft:oak_fence;;9;64;21;NULL +minecraft:oak_fence;;9;64;22;NULL +minecraft:oak_fence;;9;64;23;NULL +minecraft:sandstone;;10;63;9;NULL +minecraft:grass_block;;10;63;10;NULL +minecraft:grass_block;;10;63;11;NULL +minecraft:grass_block;;10;63;12;NULL +minecraft:grass_block;;10;63;13;NULL +minecraft:grass_block;;10;63;14;NULL +minecraft:grass_block;;10;63;15;NULL +minecraft:grass_block;;10;63;16;NULL +minecraft:grass_block;;10;63;17;NULL +minecraft:grass_block;;10;63;18;NULL +minecraft:grass_block;;10;63;19;NULL +minecraft:grass_block;;10;63;20;NULL +minecraft:grass_block;;10;63;21;NULL +minecraft:grass_block;;10;63;22;NULL +minecraft:sandstone;;10;63;23;NULL +minecraft:oak_fence;;10;64;9;NULL +minecraft:dandelion;;10;64;10;NULL +minecraft:poppy;;10;64;11;NULL +minecraft:poppy;;10;64;12;NULL +minecraft:poppy;;10;64;13;NULL +minecraft:dandelion;;10;64;14;NULL +minecraft:poppy;;10;64;15;NULL +minecraft:dandelion;;10;64;16;NULL +minecraft:poppy;;10;64;17;NULL +minecraft:dandelion;;10;64;18;NULL +minecraft:dandelion;;10;64;19;NULL +minecraft:poppy;;10;64;20;NULL +minecraft:poppy;;10;64;21;NULL +minecraft:dandelion;;10;64;22;NULL +minecraft:oak_fence;;10;64;23;NULL +minecraft:sandstone;;11;63;9;NULL +minecraft:grass_block;;11;63;10;NULL +minecraft:grass_block;;11;63;11;NULL +minecraft:grass_block;;11;63;12;NULL +minecraft:grass_block;;11;63;13;NULL +minecraft:grass_block;;11;63;14;NULL +minecraft:grass_block;;11;63;15;NULL +minecraft:grass_block;;11;63;16;NULL +minecraft:grass_block;;11;63;17;NULL +minecraft:grass_block;;11;63;18;NULL +minecraft:grass_block;;11;63;19;NULL +minecraft:grass_block;;11;63;20;NULL +minecraft:grass_block;;11;63;21;NULL +minecraft:grass_block;;11;63;22;NULL +minecraft:sandstone;;11;63;23;NULL +minecraft:oak_fence;;11;64;9;NULL +minecraft:poppy;;11;64;10;NULL +minecraft:poppy;;11;64;11;NULL +minecraft:dandelion;;11;64;12;NULL +minecraft:dandelion;;11;64;13;NULL +minecraft:dandelion;;11;64;14;NULL +minecraft:dandelion;;11;64;15;NULL +minecraft:poppy;;11;64;16;NULL +minecraft:dandelion;;11;64;17;NULL +minecraft:poppy;;11;64;18;NULL +minecraft:dandelion;;11;64;19;NULL +minecraft:dandelion;;11;64;20;NULL +minecraft:dandelion;;11;64;21;NULL +minecraft:dandelion;;11;64;22;NULL +minecraft:oak_fence;;11;64;23;NULL +minecraft:sandstone;;12;63;9;NULL +minecraft:grass_block;;12;63;10;NULL +minecraft:grass_block;;12;63;11;NULL +minecraft:grass_block;;12;63;12;NULL +minecraft:grass_block;;12;63;13;NULL +minecraft:grass_block;;12;63;14;NULL +minecraft:grass_block;;12;63;15;NULL +minecraft:grass_block;;12;63;16;NULL +minecraft:grass_block;;12;63;17;NULL +minecraft:grass_block;;12;63;18;NULL +minecraft:grass_block;;12;63;19;NULL +minecraft:grass_block;;12;63;20;NULL +minecraft:grass_block;;12;63;21;NULL +minecraft:grass_block;;12;63;22;NULL +minecraft:sandstone;;12;63;23;NULL +minecraft:oak_fence;;12;64;9;NULL +minecraft:dandelion;;12;64;10;NULL +minecraft:dandelion;;12;64;11;NULL +minecraft:dandelion;;12;64;12;NULL +minecraft:poppy;;12;64;13;NULL +minecraft:dandelion;;12;64;14;NULL +minecraft:poppy;;12;64;15;NULL +minecraft:dandelion;;12;64;16;NULL +minecraft:poppy;;12;64;17;NULL +minecraft:poppy;;12;64;18;NULL +minecraft:poppy;;12;64;19;NULL +minecraft:dandelion;;12;64;20;NULL +minecraft:dandelion;;12;64;21;NULL +minecraft:dandelion;;12;64;22;NULL +minecraft:oak_fence;;12;64;23;NULL +minecraft:sandstone;;13;63;9;NULL +minecraft:grass_block;;13;63;10;NULL +minecraft:grass_block;;13;63;11;NULL +minecraft:grass_block;;13;63;12;NULL +minecraft:grass_block;;13;63;13;NULL +minecraft:grass_block;;13;63;14;NULL +minecraft:grass_block;;13;63;15;NULL +minecraft:grass_block;;13;63;16;NULL +minecraft:grass_block;;13;63;17;NULL +minecraft:grass_block;;13;63;18;NULL +minecraft:grass_block;;13;63;19;NULL +minecraft:grass_block;;13;63;20;NULL +minecraft:grass_block;;13;63;21;NULL +minecraft:grass_block;;13;63;22;NULL +minecraft:sandstone;;13;63;23;NULL +minecraft:oak_fence;;13;64;9;NULL +minecraft:poppy;;13;64;10;NULL +minecraft:dandelion;;13;64;11;NULL +minecraft:poppy;;13;64;12;NULL +minecraft:dandelion;;13;64;13;NULL +minecraft:dandelion;;13;64;14;NULL +minecraft:poppy;;13;64;15;NULL +minecraft:dandelion;;13;64;16;NULL +minecraft:dandelion;;13;64;17;NULL +minecraft:dandelion;;13;64;18;NULL +minecraft:poppy;;13;64;19;NULL +minecraft:dandelion;;13;64;20;NULL +minecraft:poppy;;13;64;21;NULL +minecraft:poppy;;13;64;22;NULL +minecraft:oak_fence;;13;64;23;NULL +minecraft:sandstone;;14;63;9;NULL +minecraft:grass_block;;14;63;10;NULL +minecraft:grass_block;;14;63;11;NULL +minecraft:grass_block;;14;63;12;NULL +minecraft:grass_block;;14;63;13;NULL +minecraft:grass_block;;14;63;14;NULL +minecraft:grass_block;;14;63;15;NULL +minecraft:grass_block;;14;63;16;NULL +minecraft:grass_block;;14;63;17;NULL +minecraft:grass_block;;14;63;18;NULL +minecraft:grass_block;;14;63;19;NULL +minecraft:grass_block;;14;63;20;NULL +minecraft:grass_block;;14;63;21;NULL +minecraft:grass_block;;14;63;22;NULL +minecraft:sandstone;;14;63;23;NULL +minecraft:oak_fence;;14;64;9;NULL +minecraft:poppy;;14;64;10;NULL +minecraft:poppy;;14;64;11;NULL +minecraft:poppy;;14;64;12;NULL +minecraft:dandelion;;14;64;13;NULL +minecraft:poppy;;14;64;14;NULL +minecraft:poppy;;14;64;15;NULL +minecraft:poppy;;14;64;16;NULL +minecraft:poppy;;14;64;17;NULL +minecraft:poppy;;14;64;18;NULL +minecraft:poppy;;14;64;19;NULL +minecraft:dandelion;;14;64;20;NULL +minecraft:dandelion;;14;64;21;NULL +minecraft:dandelion;;14;64;22;NULL +minecraft:oak_fence;;14;64;23;NULL +minecraft:sandstone;;15;63;9;NULL +minecraft:grass_block;;15;63;10;NULL +minecraft:grass_block;;15;63;11;NULL +minecraft:grass_block;;15;63;12;NULL +minecraft:grass_block;;15;63;13;NULL +minecraft:grass_block;;15;63;14;NULL +minecraft:grass_block;;15;63;15;NULL +minecraft:grass_block;;15;63;16;NULL +minecraft:grass_block;;15;63;17;NULL +minecraft:grass_block;;15;63;18;NULL +minecraft:grass_block;;15;63;19;NULL +minecraft:grass_block;;15;63;20;NULL +minecraft:grass_block;;15;63;21;NULL +minecraft:grass_block;;15;63;22;NULL +minecraft:sandstone;;15;63;23;NULL +minecraft:oak_fence;;15;64;9;NULL +minecraft:poppy;;15;64;10;NULL +minecraft:dandelion;;15;64;11;NULL +minecraft:poppy;;15;64;12;NULL +minecraft:dandelion;;15;64;13;NULL +minecraft:dandelion;;15;64;14;NULL +minecraft:dandelion;;15;64;15;NULL +minecraft:dandelion;;15;64;16;NULL +minecraft:poppy;;15;64;17;NULL +minecraft:dandelion;;15;64;18;NULL +minecraft:dandelion;;15;64;19;NULL +minecraft:dandelion;;15;64;20;NULL +minecraft:poppy;;15;64;21;NULL +minecraft:poppy;;15;64;22;NULL +minecraft:oak_fence;;15;64;23;NULL +minecraft:sandstone;;16;63;9;NULL +minecraft:grass_block;;16;63;10;NULL +minecraft:grass_block;;16;63;11;NULL +minecraft:grass_block;;16;63;12;NULL +minecraft:grass_block;;16;63;13;NULL +minecraft:grass_block;;16;63;14;NULL +minecraft:grass_block;;16;63;15;NULL +minecraft:grass_block;;16;63;16;NULL +minecraft:grass_block;;16;63;17;NULL +minecraft:grass_block;;16;63;18;NULL +minecraft:grass_block;;16;63;19;NULL +minecraft:grass_block;;16;63;20;NULL +minecraft:grass_block;;16;63;21;NULL +minecraft:grass_block;;16;63;22;NULL +minecraft:sandstone;;16;63;23;NULL +minecraft:oak_fence;;16;64;9;NULL +minecraft:dandelion;;16;64;10;NULL +minecraft:poppy;;16;64;11;NULL +minecraft:poppy;;16;64;12;NULL +minecraft:dandelion;;16;64;13;NULL +minecraft:poppy;;16;64;14;NULL +minecraft:poppy;;16;64;15;NULL +minecraft:dandelion;;16;64;16;NULL +minecraft:poppy;;16;64;17;NULL +minecraft:dandelion;;16;64;18;NULL +minecraft:dandelion;;16;64;19;NULL +minecraft:dandelion;;16;64;20;NULL +minecraft:poppy;;16;64;21;NULL +minecraft:dandelion;;16;64;22;NULL +minecraft:oak_fence;;16;64;23;NULL +minecraft:sandstone;;17;63;9;NULL +minecraft:grass_block;;17;63;10;NULL +minecraft:grass_block;;17;63;11;NULL +minecraft:grass_block;;17;63;12;NULL +minecraft:grass_block;;17;63;13;NULL +minecraft:grass_block;;17;63;14;NULL +minecraft:grass_block;;17;63;15;NULL +minecraft:grass_block;;17;63;16;NULL +minecraft:grass_block;;17;63;17;NULL +minecraft:grass_block;;17;63;18;NULL +minecraft:grass_block;;17;63;19;NULL +minecraft:grass_block;;17;63;20;NULL +minecraft:grass_block;;17;63;21;NULL +minecraft:grass_block;;17;63;22;NULL +minecraft:sandstone;;17;63;23;NULL +minecraft:oak_fence;;17;64;9;NULL +minecraft:poppy;;17;64;10;NULL +minecraft:dandelion;;17;64;11;NULL +minecraft:dandelion;;17;64;12;NULL +minecraft:poppy;;17;64;13;NULL +minecraft:dandelion;;17;64;14;NULL +minecraft:poppy;;17;64;15;NULL +minecraft:poppy;;17;64;16;NULL +minecraft:poppy;;17;64;17;NULL +minecraft:poppy;;17;64;18;NULL +minecraft:poppy;;17;64;19;NULL +minecraft:poppy;;17;64;20;NULL +minecraft:poppy;;17;64;21;NULL +minecraft:poppy;;17;64;22;NULL +minecraft:oak_fence;;17;64;23;NULL +minecraft:sandstone;;18;63;9;NULL +minecraft:grass_block;;18;63;10;NULL +minecraft:grass_block;;18;63;11;NULL +minecraft:grass_block;;18;63;12;NULL +minecraft:grass_block;;18;63;13;NULL +minecraft:grass_block;;18;63;14;NULL +minecraft:grass_block;;18;63;15;NULL +minecraft:grass_block;;18;63;16;NULL +minecraft:grass_block;;18;63;17;NULL +minecraft:grass_block;;18;63;18;NULL +minecraft:grass_block;;18;63;19;NULL +minecraft:grass_block;;18;63;20;NULL +minecraft:grass_block;;18;63;21;NULL +minecraft:grass_block;;18;63;22;NULL +minecraft:sandstone;;18;63;23;NULL +minecraft:oak_fence;;18;64;9;NULL +minecraft:poppy;;18;64;10;NULL +minecraft:dandelion;;18;64;11;NULL +minecraft:dandelion;;18;64;12;NULL +minecraft:dandelion;;18;64;13;NULL +minecraft:poppy;;18;64;14;NULL +minecraft:dandelion;;18;64;15;NULL +minecraft:poppy;;18;64;16;NULL +minecraft:poppy;;18;64;17;NULL +minecraft:dandelion;;18;64;18;NULL +minecraft:dandelion;;18;64;19;NULL +minecraft:poppy;;18;64;20;NULL +minecraft:poppy;;18;64;21;NULL +minecraft:dandelion;;18;64;22;NULL +minecraft:oak_fence;;18;64;23;NULL +minecraft:sandstone;;19;63;9;NULL +minecraft:grass_block;;19;63;10;NULL +minecraft:grass_block;;19;63;11;NULL +minecraft:grass_block;;19;63;12;NULL +minecraft:grass_block;;19;63;13;NULL +minecraft:grass_block;;19;63;14;NULL +minecraft:grass_block;;19;63;15;NULL +minecraft:grass_block;;19;63;16;NULL +minecraft:grass_block;;19;63;17;NULL +minecraft:grass_block;;19;63;18;NULL +minecraft:grass_block;;19;63;19;NULL +minecraft:grass_block;;19;63;20;NULL +minecraft:grass_block;;19;63;21;NULL +minecraft:grass_block;;19;63;22;NULL +minecraft:sandstone;;19;63;23;NULL +minecraft:oak_fence;;19;64;9;NULL +minecraft:dandelion;;19;64;10;NULL +minecraft:poppy;;19;64;11;NULL +minecraft:dandelion;;19;64;12;NULL +minecraft:poppy;;19;64;13;NULL +minecraft:dandelion;;19;64;14;NULL +minecraft:dandelion;;19;64;15;NULL +minecraft:poppy;;19;64;16;NULL +minecraft:poppy;;19;64;17;NULL +minecraft:dandelion;;19;64;18;NULL +minecraft:dandelion;;19;64;19;NULL +minecraft:poppy;;19;64;20;NULL +minecraft:poppy;;19;64;21;NULL +minecraft:poppy;;19;64;22;NULL +minecraft:oak_fence;;19;64;23;NULL +minecraft:sandstone;;20;63;9;NULL +minecraft:grass_block;;20;63;10;NULL +minecraft:grass_block;;20;63;11;NULL +minecraft:grass_block;;20;63;12;NULL +minecraft:grass_block;;20;63;13;NULL +minecraft:grass_block;;20;63;14;NULL +minecraft:grass_block;;20;63;15;NULL +minecraft:grass_block;;20;63;16;NULL +minecraft:grass_block;;20;63;17;NULL +minecraft:grass_block;;20;63;18;NULL +minecraft:grass_block;;20;63;19;NULL +minecraft:grass_block;;20;63;20;NULL +minecraft:grass_block;;20;63;21;NULL +minecraft:grass_block;;20;63;22;NULL +minecraft:sandstone;;20;63;23;NULL +minecraft:oak_fence;;20;64;9;NULL +minecraft:dandelion;;20;64;10;NULL +minecraft:poppy;;20;64;11;NULL +minecraft:poppy;;20;64;12;NULL +minecraft:poppy;;20;64;13;NULL +minecraft:poppy;;20;64;14;NULL +minecraft:poppy;;20;64;15;NULL +minecraft:poppy;;20;64;16;NULL +minecraft:dandelion;;20;64;17;NULL +minecraft:dandelion;;20;64;18;NULL +minecraft:poppy;;20;64;19;NULL +minecraft:dandelion;;20;64;20;NULL +minecraft:dandelion;;20;64;21;NULL +minecraft:poppy;;20;64;22;NULL +minecraft:oak_fence;;20;64;23;NULL +minecraft:sandstone;;21;63;9;NULL +minecraft:grass_block;;21;63;10;NULL +minecraft:grass_block;;21;63;11;NULL +minecraft:grass_block;;21;63;12;NULL +minecraft:grass_block;;21;63;13;NULL +minecraft:grass_block;;21;63;14;NULL +minecraft:grass_block;;21;63;15;NULL +minecraft:grass_block;;21;63;16;NULL +minecraft:grass_block;;21;63;17;NULL +minecraft:grass_block;;21;63;18;NULL +minecraft:grass_block;;21;63;19;NULL +minecraft:grass_block;;21;63;20;NULL +minecraft:grass_block;;21;63;21;NULL +minecraft:grass_block;;21;63;22;NULL +minecraft:sandstone;;21;63;23;NULL +minecraft:oak_fence;;21;64;9;NULL +minecraft:poppy;;21;64;10;NULL +minecraft:poppy;;21;64;11;NULL +minecraft:dandelion;;21;64;12;NULL +minecraft:dandelion;;21;64;13;NULL +minecraft:dandelion;;21;64;14;NULL +minecraft:poppy;;21;64;15;NULL +minecraft:dandelion;;21;64;16;NULL +minecraft:dandelion;;21;64;17;NULL +minecraft:poppy;;21;64;18;NULL +minecraft:dandelion;;21;64;19;NULL +minecraft:poppy;;21;64;20;NULL +minecraft:dandelion;;21;64;21;NULL +minecraft:poppy;;21;64;22;NULL +minecraft:oak_fence;;21;64;23;NULL +minecraft:sandstone;;22;63;9;NULL +minecraft:grass_block;;22;63;10;NULL +minecraft:grass_block;;22;63;11;NULL +minecraft:grass_block;;22;63;12;NULL +minecraft:grass_block;;22;63;13;NULL +minecraft:grass_block;;22;63;14;NULL +minecraft:grass_block;;22;63;15;NULL +minecraft:grass_block;;22;63;16;NULL +minecraft:grass_block;;22;63;17;NULL +minecraft:grass_block;;22;63;18;NULL +minecraft:grass_block;;22;63;19;NULL +minecraft:grass_block;;22;63;20;NULL +minecraft:grass_block;;22;63;21;NULL +minecraft:grass_block;;22;63;22;NULL +minecraft:sandstone;;22;63;23;NULL +minecraft:oak_fence;;22;64;9;NULL +minecraft:dandelion;;22;64;10;NULL +minecraft:poppy;;22;64;11;NULL +minecraft:poppy;;22;64;12;NULL +minecraft:dandelion;;22;64;13;NULL +minecraft:poppy;;22;64;14;NULL +minecraft:dandelion;;22;64;15;NULL +minecraft:dandelion;;22;64;16;NULL +minecraft:poppy;;22;64;17;NULL +minecraft:poppy;;22;64;18;NULL +minecraft:poppy;;22;64;19;NULL +minecraft:poppy;;22;64;20;NULL +minecraft:poppy;;22;64;21;NULL +minecraft:poppy;;22;64;22;NULL +minecraft:oak_fence;;22;64;23;NULL +minecraft:sandstone;;23;63;9;NULL +minecraft:sandstone;;23;63;10;NULL +minecraft:sandstone;;23;63;11;NULL +minecraft:sandstone;;23;63;12;NULL +minecraft:sandstone;;23;63;13;NULL +minecraft:sandstone;;23;63;14;NULL +minecraft:sandstone;;23;63;15;NULL +minecraft:sandstone;;23;63;16;NULL +minecraft:sandstone;;23;63;17;NULL +minecraft:sandstone;;23;63;18;NULL +minecraft:sandstone;;23;63;19;NULL +minecraft:sandstone;;23;63;20;NULL +minecraft:sandstone;;23;63;21;NULL +minecraft:sandstone;;23;63;22;NULL +minecraft:sandstone;;23;63;23;NULL +minecraft:oak_fence;;23;64;9;NULL +minecraft:oak_fence;;23;64;10;NULL +minecraft:oak_fence;;23;64;11;NULL +minecraft:oak_fence;;23;64;12;NULL +minecraft:oak_fence;;23;64;13;NULL +minecraft:oak_fence;;23;64;14;NULL +minecraft:oak_fence;;23;64;15;NULL +minecraft:oak_fence;;23;64;16;NULL +minecraft:oak_fence;;23;64;17;NULL +minecraft:oak_fence;;23;64;18;NULL +minecraft:oak_fence;;23;64;19;NULL +minecraft:oak_fence;;23;64;20;NULL +minecraft:oak_fence;;23;64;21;NULL +minecraft:oak_fence;;23;64;22;NULL +minecraft:oak_fence;;23;64;23;NULL +minecraft:red_wool;;15;63;9;NULL +minecraft:oak_fence;;15;64;9;NULL +minecraft:oak_fence;;15;65;9;NULL +minecraft:oak_fence;;15;66;9;NULL +minecraft:red_wool;;16;63;9;NULL +minecraft:air;;16;64;9;NULL +minecraft:air;;16;65;9;NULL +minecraft:oak_fence;;16;66;9;NULL +minecraft:red_wool;;17;63;9;NULL +minecraft:oak_fence;;17;64;9;NULL +minecraft:oak_fence;;17;65;9;NULL +minecraft:oak_fence;;17;66;9;NULL +minecraft:lime_wool;;15;63;23;NULL +minecraft:oak_fence;;15;64;23;NULL +minecraft:oak_fence;;15;65;23;NULL +minecraft:oak_fence;;15;66;23;NULL +minecraft:lime_wool;;16;63;23;NULL +minecraft:air;;16;64;23;NULL +minecraft:air;;16;65;23;NULL +minecraft:oak_fence;;16;66;23;NULL +minecraft:lime_wool;;17;63;23;NULL +minecraft:oak_fence;;17;64;23;NULL +minecraft:oak_fence;;17;65;23;NULL +minecraft:oak_fence;;17;66;23;NULL +minecraft:light_blue_wool;;9;63;15;NULL +minecraft:light_blue_wool;;9;63;16;NULL +minecraft:light_blue_wool;;9;63;17;NULL +minecraft:oak_fence;;9;64;15;NULL +minecraft:air;;9;64;16;NULL +minecraft:oak_fence;;9;64;17;NULL +minecraft:oak_fence;;9;65;15;NULL +minecraft:air;;9;65;16;NULL +minecraft:oak_fence;;9;65;17;NULL +minecraft:oak_fence;;9;66;15;NULL +minecraft:oak_fence;;9;66;16;NULL +minecraft:oak_fence;;9;66;17;NULL +minecraft:yellow_wool;;23;63;15;NULL +minecraft:yellow_wool;;23;63;16;NULL +minecraft:yellow_wool;;23;63;17;NULL +minecraft:oak_fence;;23;64;15;NULL +minecraft:air;;23;64;16;NULL +minecraft:oak_fence;;23;64;17;NULL +minecraft:oak_fence;;23;65;15;NULL +minecraft:air;;23;65;16;NULL +minecraft:oak_fence;;23;65;17;NULL +minecraft:oak_fence;;23;66;15;NULL +minecraft:oak_fence;;23;66;16;NULL +minecraft:oak_fence;;23;66;17;NULL +minecraft:sign;rotation=6;9;65;9;HelloWorld +minecraft:sign;rotation=10;23;65;9;HelloWorld +minecraft:sign;rotation=2;9;65;23;HelloWorld +minecraft:sign;rotation=14;23;65;23;HelloWorld +minecraft:pig_place;;16;65;16;HelloWorld +minecraft:sign;rotation=14;23;65;22;BuiltMetric1: 4 +minecraft:sign;rotation=14;23;65;21;BuiltMetric2: 0 +minecraft:sign;rotation=14;23;65;20;BuiltMetric3: 0 +minecraft:iron_block;;12;64;12;NULL +minecraft:iron_block;;12;64;13;NULL +minecraft:iron_block;;12;64;14;NULL +minecraft:iron_block;;12;64;15;NULL +minecraft:iron_block;;12;64;16;NULL +minecraft:iron_block;;12;64;17;NULL +minecraft:iron_block;;12;64;18;NULL +minecraft:iron_block;;12;64;19;NULL +minecraft:iron_block;;12;64;20;NULL +minecraft:iron_block;;12;65;12;NULL +minecraft:glass;;12;65;13;NULL +minecraft:iron_block;;12;65;14;NULL +minecraft:glass;;12;65;15;NULL +minecraft:glass;;12;65;16;NULL +minecraft:glass;;12;65;17;NULL +minecraft:glass;;12;65;18;NULL +minecraft:iron_block;;12;65;19;NULL +minecraft:iron_block;;12;65;20;NULL +minecraft:iron_block;;12;66;12;NULL +minecraft:iron_block;;12;66;13;NULL +minecraft:iron_block;;12;66;14;NULL +minecraft:iron_block;;12;66;15;NULL +minecraft:iron_block;;12;66;16;NULL +minecraft:iron_block;;12;66;17;NULL +minecraft:iron_block;;12;66;18;NULL +minecraft:iron_block;;12;66;19;NULL +minecraft:iron_block;;12;66;20;NULL +minecraft:iron_block;;12;67;12;NULL +minecraft:glass;;12;67;13;NULL +minecraft:iron_block;;12;67;14;NULL +minecraft:glass;;12;67;15;NULL +minecraft:glass;;12;67;16;NULL +minecraft:glass;;12;67;17;NULL +minecraft:glass;;12;67;18;NULL +minecraft:iron_block;;12;67;19;NULL +minecraft:iron_block;;12;67;20;NULL +minecraft:iron_block;;12;68;12;NULL +minecraft:glass;;12;68;13;NULL +minecraft:iron_block;;12;68;14;NULL +minecraft:glass;;12;68;15;NULL +minecraft:glass;;12;68;16;NULL +minecraft:glass;;12;68;17;NULL +minecraft:glass;;12;68;18;NULL +minecraft:iron_block;;12;68;19;NULL +minecraft:iron_block;;12;68;20;NULL +minecraft:iron_block;;12;69;12;NULL +minecraft:glass;;12;69;13;NULL +minecraft:iron_block;;12;69;14;NULL +minecraft:glass;;12;69;15;NULL +minecraft:glass;;12;69;16;NULL +minecraft:glass;;12;69;17;NULL +minecraft:glass;;12;69;18;NULL +minecraft:iron_block;;12;69;19;NULL +minecraft:iron_block;;12;69;20;NULL +minecraft:iron_block;;12;70;12;NULL +minecraft:glass;;12;70;13;NULL +minecraft:iron_block;;12;70;14;NULL +minecraft:glass;;12;70;15;NULL +minecraft:glass;;12;70;16;NULL +minecraft:glass;;12;70;17;NULL +minecraft:glass;;12;70;18;NULL +minecraft:iron_block;;12;70;19;NULL +minecraft:iron_block;;12;70;20;NULL +minecraft:iron_block;;12;71;12;NULL +minecraft:iron_block;;12;71;13;NULL +minecraft:iron_block;;12;71;14;NULL +minecraft:iron_block;;12;71;15;NULL +minecraft:iron_block;;12;71;16;NULL +minecraft:iron_block;;12;71;17;NULL +minecraft:iron_block;;12;71;18;NULL +minecraft:iron_block;;12;71;19;NULL +minecraft:iron_block;;12;71;20;NULL +minecraft:iron_block;;12;72;12;NULL +minecraft:glass;;12;72;13;NULL +minecraft:iron_block;;12;72;14;NULL +minecraft:glass;;12;72;15;NULL +minecraft:glass;;12;72;16;NULL +minecraft:glass;;12;72;17;NULL +minecraft:glass;;12;72;18;NULL +minecraft:iron_block;;12;72;19;NULL +minecraft:iron_block;;12;72;20;NULL +minecraft:iron_block;;12;73;12;NULL +minecraft:glass;;12;73;13;NULL +minecraft:iron_block;;12;73;14;NULL +minecraft:glass;;12;73;15;NULL +minecraft:glass;;12;73;16;NULL +minecraft:glass;;12;73;17;NULL +minecraft:glass;;12;73;18;NULL +minecraft:iron_block;;12;73;19;NULL +minecraft:iron_block;;12;73;20;NULL +minecraft:iron_block;;12;74;12;NULL +minecraft:iron_block;;12;74;13;NULL +minecraft:iron_block;;12;74;14;NULL +minecraft:iron_block;;12;74;15;NULL +minecraft:iron_block;;12;74;16;NULL +minecraft:iron_block;;12;74;17;NULL +minecraft:iron_block;;12;74;18;NULL +minecraft:iron_block;;12;74;19;NULL +minecraft:iron_block;;12;74;20;NULL +minecraft:iron_block;;20;64;12;NULL +minecraft:iron_block;;20;64;13;NULL +minecraft:iron_block;;20;64;14;NULL +minecraft:iron_block;;20;64;15;NULL +minecraft:iron_block;;20;64;16;NULL +minecraft:iron_block;;20;64;17;NULL +minecraft:iron_block;;20;64;18;NULL +minecraft:iron_block;;20;64;19;NULL +minecraft:iron_block;;20;64;20;NULL +minecraft:iron_block;;20;65;12;NULL +minecraft:glass;;20;65;13;NULL +minecraft:iron_block;;20;65;14;NULL +minecraft:glass;;20;65;15;NULL +minecraft:glass;;20;65;16;NULL +minecraft:glass;;20;65;17;NULL +minecraft:glass;;20;65;18;NULL +minecraft:iron_block;;20;65;19;NULL +minecraft:iron_block;;20;65;20;NULL +minecraft:iron_block;;20;66;12;NULL +minecraft:iron_block;;20;66;13;NULL +minecraft:iron_block;;20;66;14;NULL +minecraft:iron_block;;20;66;15;NULL +minecraft:iron_block;;20;66;16;NULL +minecraft:iron_block;;20;66;17;NULL +minecraft:iron_block;;20;66;18;NULL +minecraft:iron_block;;20;66;19;NULL +minecraft:iron_block;;20;66;20;NULL +minecraft:iron_block;;20;67;12;NULL +minecraft:glass;;20;67;13;NULL +minecraft:iron_block;;20;67;14;NULL +minecraft:glass;;20;67;15;NULL +minecraft:glass;;20;67;16;NULL +minecraft:glass;;20;67;17;NULL +minecraft:glass;;20;67;18;NULL +minecraft:iron_block;;20;67;19;NULL +minecraft:iron_block;;20;67;20;NULL +minecraft:iron_block;;20;68;12;NULL +minecraft:glass;;20;68;13;NULL +minecraft:iron_block;;20;68;14;NULL +minecraft:glass;;20;68;15;NULL +minecraft:glass;;20;68;16;NULL +minecraft:glass;;20;68;17;NULL +minecraft:glass;;20;68;18;NULL +minecraft:iron_block;;20;68;19;NULL +minecraft:iron_block;;20;68;20;NULL +minecraft:iron_block;;20;69;12;NULL +minecraft:glass;;20;69;13;NULL +minecraft:iron_block;;20;69;14;NULL +minecraft:glass;;20;69;15;NULL +minecraft:glass;;20;69;16;NULL +minecraft:glass;;20;69;17;NULL +minecraft:glass;;20;69;18;NULL +minecraft:iron_block;;20;69;19;NULL +minecraft:iron_block;;20;69;20;NULL +minecraft:iron_block;;20;70;12;NULL +minecraft:glass;;20;70;13;NULL +minecraft:iron_block;;20;70;14;NULL +minecraft:glass;;20;70;15;NULL +minecraft:glass;;20;70;16;NULL +minecraft:glass;;20;70;17;NULL +minecraft:glass;;20;70;18;NULL +minecraft:iron_block;;20;70;19;NULL +minecraft:iron_block;;20;70;20;NULL +minecraft:iron_block;;20;71;12;NULL +minecraft:iron_block;;20;71;13;NULL +minecraft:iron_block;;20;71;14;NULL +minecraft:iron_block;;20;71;15;NULL +minecraft:iron_block;;20;71;16;NULL +minecraft:iron_block;;20;71;17;NULL +minecraft:iron_block;;20;71;18;NULL +minecraft:iron_block;;20;71;19;NULL +minecraft:iron_block;;20;71;20;NULL +minecraft:iron_block;;20;72;12;NULL +minecraft:glass;;20;72;13;NULL +minecraft:iron_block;;20;72;14;NULL +minecraft:glass;;20;72;15;NULL +minecraft:glass;;20;72;16;NULL +minecraft:glass;;20;72;17;NULL +minecraft:glass;;20;72;18;NULL +minecraft:iron_block;;20;72;19;NULL +minecraft:iron_block;;20;72;20;NULL +minecraft:iron_block;;20;73;12;NULL +minecraft:glass;;20;73;13;NULL +minecraft:iron_block;;20;73;14;NULL +minecraft:glass;;20;73;15;NULL +minecraft:glass;;20;73;16;NULL +minecraft:glass;;20;73;17;NULL +minecraft:glass;;20;73;18;NULL +minecraft:iron_block;;20;73;19;NULL +minecraft:iron_block;;20;73;20;NULL +minecraft:iron_block;;20;74;12;NULL +minecraft:iron_block;;20;74;13;NULL +minecraft:iron_block;;20;74;14;NULL +minecraft:iron_block;;20;74;15;NULL +minecraft:iron_block;;20;74;16;NULL +minecraft:iron_block;;20;74;17;NULL +minecraft:iron_block;;20;74;18;NULL +minecraft:iron_block;;20;74;19;NULL +minecraft:iron_block;;20;74;20;NULL +minecraft:iron_block;;12;64;12;NULL +minecraft:iron_block;;12;65;12;NULL +minecraft:iron_block;;12;66;12;NULL +minecraft:iron_block;;12;67;12;NULL +minecraft:iron_block;;12;68;12;NULL +minecraft:iron_block;;12;69;12;NULL +minecraft:iron_block;;12;70;12;NULL +minecraft:iron_block;;12;71;12;NULL +minecraft:iron_block;;12;72;12;NULL +minecraft:iron_block;;12;73;12;NULL +minecraft:iron_block;;12;74;12;NULL +minecraft:iron_block;;13;64;12;NULL +minecraft:glass;;13;65;12;NULL +minecraft:iron_block;;13;66;12;NULL +minecraft:glass;;13;67;12;NULL +minecraft:glass;;13;68;12;NULL +minecraft:glass;;13;69;12;NULL +minecraft:glass;;13;70;12;NULL +minecraft:iron_block;;13;71;12;NULL +minecraft:glass;;13;72;12;NULL +minecraft:glass;;13;73;12;NULL +minecraft:iron_block;;13;74;12;NULL +minecraft:iron_block;;14;64;12;NULL +minecraft:iron_block;;14;65;12;NULL +minecraft:iron_block;;14;66;12;NULL +minecraft:iron_block;;14;67;12;NULL +minecraft:iron_block;;14;68;12;NULL +minecraft:iron_block;;14;69;12;NULL +minecraft:iron_block;;14;70;12;NULL +minecraft:iron_block;;14;71;12;NULL +minecraft:iron_block;;14;72;12;NULL +minecraft:iron_block;;14;73;12;NULL +minecraft:iron_block;;14;74;12;NULL +minecraft:iron_block;;15;64;12;NULL +minecraft:glass;;15;65;12;NULL +minecraft:iron_block;;15;66;12;NULL +minecraft:glass;;15;67;12;NULL +minecraft:glass;;15;68;12;NULL +minecraft:glass;;15;69;12;NULL +minecraft:glass;;15;70;12;NULL +minecraft:iron_block;;15;71;12;NULL +minecraft:glass;;15;72;12;NULL +minecraft:glass;;15;73;12;NULL +minecraft:iron_block;;15;74;12;NULL +minecraft:iron_block;;16;64;12;NULL +minecraft:glass;;16;65;12;NULL +minecraft:iron_block;;16;66;12;NULL +minecraft:glass;;16;67;12;NULL +minecraft:glass;;16;68;12;NULL +minecraft:glass;;16;69;12;NULL +minecraft:glass;;16;70;12;NULL +minecraft:iron_block;;16;71;12;NULL +minecraft:glass;;16;72;12;NULL +minecraft:glass;;16;73;12;NULL +minecraft:iron_block;;16;74;12;NULL +minecraft:iron_block;;17;64;12;NULL +minecraft:glass;;17;65;12;NULL +minecraft:iron_block;;17;66;12;NULL +minecraft:glass;;17;67;12;NULL +minecraft:glass;;17;68;12;NULL +minecraft:glass;;17;69;12;NULL +minecraft:glass;;17;70;12;NULL +minecraft:iron_block;;17;71;12;NULL +minecraft:glass;;17;72;12;NULL +minecraft:glass;;17;73;12;NULL +minecraft:iron_block;;17;74;12;NULL +minecraft:iron_block;;18;64;12;NULL +minecraft:glass;;18;65;12;NULL +minecraft:iron_block;;18;66;12;NULL +minecraft:glass;;18;67;12;NULL +minecraft:glass;;18;68;12;NULL +minecraft:glass;;18;69;12;NULL +minecraft:glass;;18;70;12;NULL +minecraft:iron_block;;18;71;12;NULL +minecraft:glass;;18;72;12;NULL +minecraft:glass;;18;73;12;NULL +minecraft:iron_block;;18;74;12;NULL +minecraft:iron_block;;19;64;12;NULL +minecraft:iron_block;;19;65;12;NULL +minecraft:iron_block;;19;66;12;NULL +minecraft:iron_block;;19;67;12;NULL +minecraft:iron_block;;19;68;12;NULL +minecraft:iron_block;;19;69;12;NULL +minecraft:iron_block;;19;70;12;NULL +minecraft:iron_block;;19;71;12;NULL +minecraft:iron_block;;19;72;12;NULL +minecraft:iron_block;;19;73;12;NULL +minecraft:iron_block;;19;74;12;NULL +minecraft:iron_block;;20;64;12;NULL +minecraft:iron_block;;20;65;12;NULL +minecraft:iron_block;;20;66;12;NULL +minecraft:iron_block;;20;67;12;NULL +minecraft:iron_block;;20;68;12;NULL +minecraft:iron_block;;20;69;12;NULL +minecraft:iron_block;;20;70;12;NULL +minecraft:iron_block;;20;71;12;NULL +minecraft:iron_block;;20;72;12;NULL +minecraft:iron_block;;20;73;12;NULL +minecraft:iron_block;;20;74;12;NULL +minecraft:iron_block;;12;64;20;NULL +minecraft:iron_block;;12;65;20;NULL +minecraft:iron_block;;12;66;20;NULL +minecraft:iron_block;;12;67;20;NULL +minecraft:iron_block;;12;68;20;NULL +minecraft:iron_block;;12;69;20;NULL +minecraft:iron_block;;12;70;20;NULL +minecraft:iron_block;;12;71;20;NULL +minecraft:iron_block;;12;72;20;NULL +minecraft:iron_block;;12;73;20;NULL +minecraft:iron_block;;12;74;20;NULL +minecraft:iron_block;;13;64;20;NULL +minecraft:glass;;13;65;20;NULL +minecraft:iron_block;;13;66;20;NULL +minecraft:glass;;13;67;20;NULL +minecraft:glass;;13;68;20;NULL +minecraft:glass;;13;69;20;NULL +minecraft:glass;;13;70;20;NULL +minecraft:iron_block;;13;71;20;NULL +minecraft:glass;;13;72;20;NULL +minecraft:glass;;13;73;20;NULL +minecraft:iron_block;;13;74;20;NULL +minecraft:iron_block;;14;64;20;NULL +minecraft:iron_block;;14;65;20;NULL +minecraft:iron_block;;14;66;20;NULL +minecraft:iron_block;;14;67;20;NULL +minecraft:iron_block;;14;68;20;NULL +minecraft:iron_block;;14;69;20;NULL +minecraft:iron_block;;14;70;20;NULL +minecraft:iron_block;;14;71;20;NULL +minecraft:iron_block;;14;72;20;NULL +minecraft:iron_block;;14;73;20;NULL +minecraft:iron_block;;14;74;20;NULL +minecraft:iron_block;;15;64;20;NULL +minecraft:glass;;15;65;20;NULL +minecraft:iron_block;;15;66;20;NULL +minecraft:glass;;15;67;20;NULL +minecraft:glass;;15;68;20;NULL +minecraft:glass;;15;69;20;NULL +minecraft:glass;;15;70;20;NULL +minecraft:iron_block;;15;71;20;NULL +minecraft:glass;;15;72;20;NULL +minecraft:glass;;15;73;20;NULL +minecraft:iron_block;;15;74;20;NULL +minecraft:iron_block;;16;64;20;NULL +minecraft:glass;;16;65;20;NULL +minecraft:iron_block;;16;66;20;NULL +minecraft:glass;;16;67;20;NULL +minecraft:glass;;16;68;20;NULL +minecraft:glass;;16;69;20;NULL +minecraft:glass;;16;70;20;NULL +minecraft:iron_block;;16;71;20;NULL +minecraft:glass;;16;72;20;NULL +minecraft:glass;;16;73;20;NULL +minecraft:iron_block;;16;74;20;NULL +minecraft:iron_block;;17;64;20;NULL +minecraft:glass;;17;65;20;NULL +minecraft:iron_block;;17;66;20;NULL +minecraft:glass;;17;67;20;NULL +minecraft:glass;;17;68;20;NULL +minecraft:glass;;17;69;20;NULL +minecraft:glass;;17;70;20;NULL +minecraft:iron_block;;17;71;20;NULL +minecraft:glass;;17;72;20;NULL +minecraft:glass;;17;73;20;NULL +minecraft:iron_block;;17;74;20;NULL +minecraft:iron_block;;18;64;20;NULL +minecraft:glass;;18;65;20;NULL +minecraft:iron_block;;18;66;20;NULL +minecraft:glass;;18;67;20;NULL +minecraft:glass;;18;68;20;NULL +minecraft:glass;;18;69;20;NULL +minecraft:glass;;18;70;20;NULL +minecraft:iron_block;;18;71;20;NULL +minecraft:glass;;18;72;20;NULL +minecraft:glass;;18;73;20;NULL +minecraft:iron_block;;18;74;20;NULL +minecraft:iron_block;;19;64;20;NULL +minecraft:iron_block;;19;65;20;NULL +minecraft:iron_block;;19;66;20;NULL +minecraft:iron_block;;19;67;20;NULL +minecraft:iron_block;;19;68;20;NULL +minecraft:iron_block;;19;69;20;NULL +minecraft:iron_block;;19;70;20;NULL +minecraft:iron_block;;19;71;20;NULL +minecraft:iron_block;;19;72;20;NULL +minecraft:iron_block;;19;73;20;NULL +minecraft:iron_block;;19;74;20;NULL +minecraft:iron_block;;20;64;20;NULL +minecraft:iron_block;;20;65;20;NULL +minecraft:iron_block;;20;66;20;NULL +minecraft:iron_block;;20;67;20;NULL +minecraft:iron_block;;20;68;20;NULL +minecraft:iron_block;;20;69;20;NULL +minecraft:iron_block;;20;70;20;NULL +minecraft:iron_block;;20;71;20;NULL +minecraft:iron_block;;20;72;20;NULL +minecraft:iron_block;;20;73;20;NULL +minecraft:iron_block;;20;74;20;NULL +minecraft:iron_block;;12;64;12;NULL +minecraft:iron_block;;12;64;13;NULL +minecraft:iron_block;;12;64;14;NULL +minecraft:iron_block;;12;64;15;NULL +minecraft:iron_block;;12;64;16;NULL +minecraft:iron_block;;12;64;17;NULL +minecraft:iron_block;;12;64;18;NULL +minecraft:iron_block;;12;64;19;NULL +minecraft:iron_block;;12;64;20;NULL +minecraft:iron_block;;13;64;12;NULL +minecraft:iron_block;;13;64;13;NULL +minecraft:iron_block;;13;64;14;NULL +minecraft:iron_block;;13;64;15;NULL +minecraft:iron_block;;13;64;16;NULL +minecraft:iron_block;;13;64;17;NULL +minecraft:iron_block;;13;64;18;NULL +minecraft:iron_block;;13;64;19;NULL +minecraft:iron_block;;13;64;20;NULL +minecraft:iron_block;;14;64;12;NULL +minecraft:iron_block;;14;64;13;NULL +minecraft:iron_block;;14;64;14;NULL +minecraft:iron_block;;14;64;15;NULL +minecraft:iron_block;;14;64;16;NULL +minecraft:iron_block;;14;64;17;NULL +minecraft:iron_block;;14;64;18;NULL +minecraft:iron_block;;14;64;19;NULL +minecraft:iron_block;;14;64;20;NULL +minecraft:iron_block;;15;64;12;NULL +minecraft:iron_block;;15;64;13;NULL +minecraft:iron_block;;15;64;14;NULL +minecraft:iron_block;;15;64;15;NULL +minecraft:iron_block;;15;64;16;NULL +minecraft:iron_block;;15;64;17;NULL +minecraft:iron_block;;15;64;18;NULL +minecraft:iron_block;;15;64;19;NULL +minecraft:iron_block;;15;64;20;NULL +minecraft:iron_block;;16;64;12;NULL +minecraft:iron_block;;16;64;13;NULL +minecraft:iron_block;;16;64;14;NULL +minecraft:iron_block;;16;64;15;NULL +minecraft:iron_block;;16;64;16;NULL +minecraft:iron_block;;16;64;17;NULL +minecraft:iron_block;;16;64;18;NULL +minecraft:iron_block;;16;64;19;NULL +minecraft:iron_block;;16;64;20;NULL +minecraft:iron_block;;17;64;12;NULL +minecraft:iron_block;;17;64;13;NULL +minecraft:iron_block;;17;64;14;NULL +minecraft:iron_block;;17;64;15;NULL +minecraft:iron_block;;17;64;16;NULL +minecraft:iron_block;;17;64;17;NULL +minecraft:iron_block;;17;64;18;NULL +minecraft:iron_block;;17;64;19;NULL +minecraft:iron_block;;17;64;20;NULL +minecraft:iron_block;;18;64;12;NULL +minecraft:iron_block;;18;64;13;NULL +minecraft:iron_block;;18;64;14;NULL +minecraft:iron_block;;18;64;15;NULL +minecraft:iron_block;;18;64;16;NULL +minecraft:iron_block;;18;64;17;NULL +minecraft:iron_block;;18;64;18;NULL +minecraft:iron_block;;18;64;19;NULL +minecraft:iron_block;;18;64;20;NULL +minecraft:iron_block;;19;64;12;NULL +minecraft:iron_block;;19;64;13;NULL +minecraft:iron_block;;19;64;14;NULL +minecraft:iron_block;;19;64;15;NULL +minecraft:iron_block;;19;64;16;NULL +minecraft:iron_block;;19;64;17;NULL +minecraft:iron_block;;19;64;18;NULL +minecraft:iron_block;;19;64;19;NULL +minecraft:iron_block;;19;64;20;NULL +minecraft:iron_block;;20;64;12;NULL +minecraft:iron_block;;20;64;13;NULL +minecraft:iron_block;;20;64;14;NULL +minecraft:iron_block;;20;64;15;NULL +minecraft:iron_block;;20;64;16;NULL +minecraft:iron_block;;20;64;17;NULL +minecraft:iron_block;;20;64;18;NULL +minecraft:iron_block;;20;64;19;NULL +minecraft:iron_block;;20;64;20;NULL +minecraft:iron_block;;12;74;12;NULL +minecraft:iron_block;;12;74;13;NULL +minecraft:iron_block;;12;74;14;NULL +minecraft:iron_block;;12;74;15;NULL +minecraft:iron_block;;12;74;16;NULL +minecraft:iron_block;;12;74;17;NULL +minecraft:iron_block;;12;74;18;NULL +minecraft:iron_block;;12;74;19;NULL +minecraft:iron_block;;12;74;20;NULL +minecraft:iron_block;;13;74;12;NULL +minecraft:glass;;13;74;13;NULL +minecraft:glass;;13;74;14;NULL +minecraft:glass;;13;74;15;NULL +minecraft:glass;;13;74;16;NULL +minecraft:glass;;13;74;17;NULL +minecraft:glass;;13;74;18;NULL +minecraft:glass;;13;74;19;NULL +minecraft:iron_block;;13;74;20;NULL +minecraft:iron_block;;14;74;12;NULL +minecraft:glass;;14;74;13;NULL +minecraft:glass;;14;74;14;NULL +minecraft:glass;;14;74;15;NULL +minecraft:glass;;14;74;16;NULL +minecraft:glass;;14;74;17;NULL +minecraft:glass;;14;74;18;NULL +minecraft:glass;;14;74;19;NULL +minecraft:iron_block;;14;74;20;NULL +minecraft:iron_block;;15;74;12;NULL +minecraft:glass;;15;74;13;NULL +minecraft:glass;;15;74;14;NULL +minecraft:glass;;15;74;15;NULL +minecraft:glass;;15;74;16;NULL +minecraft:glass;;15;74;17;NULL +minecraft:glass;;15;74;18;NULL +minecraft:glass;;15;74;19;NULL +minecraft:iron_block;;15;74;20;NULL +minecraft:iron_block;;16;74;12;NULL +minecraft:glass;;16;74;13;NULL +minecraft:glass;;16;74;14;NULL +minecraft:glass;;16;74;15;NULL +minecraft:glass;;16;74;16;NULL +minecraft:glass;;16;74;17;NULL +minecraft:glass;;16;74;18;NULL +minecraft:glass;;16;74;19;NULL +minecraft:iron_block;;16;74;20;NULL +minecraft:iron_block;;17;74;12;NULL +minecraft:glass;;17;74;13;NULL +minecraft:glass;;17;74;14;NULL +minecraft:glass;;17;74;15;NULL +minecraft:glass;;17;74;16;NULL +minecraft:glass;;17;74;17;NULL +minecraft:glass;;17;74;18;NULL +minecraft:glass;;17;74;19;NULL +minecraft:iron_block;;17;74;20;NULL +minecraft:iron_block;;18;74;12;NULL +minecraft:glass;;18;74;13;NULL +minecraft:glass;;18;74;14;NULL +minecraft:glass;;18;74;15;NULL +minecraft:glass;;18;74;16;NULL +minecraft:glass;;18;74;17;NULL +minecraft:glass;;18;74;18;NULL +minecraft:glass;;18;74;19;NULL +minecraft:iron_block;;18;74;20;NULL +minecraft:iron_block;;19;74;12;NULL +minecraft:glass;;19;74;13;NULL +minecraft:glass;;19;74;14;NULL +minecraft:glass;;19;74;15;NULL +minecraft:glass;;19;74;16;NULL +minecraft:glass;;19;74;17;NULL +minecraft:glass;;19;74;18;NULL +minecraft:glass;;19;74;19;NULL +minecraft:iron_block;;19;74;20;NULL +minecraft:iron_block;;20;74;12;NULL +minecraft:iron_block;;20;74;13;NULL +minecraft:iron_block;;20;74;14;NULL +minecraft:iron_block;;20;74;15;NULL +minecraft:iron_block;;20;74;16;NULL +minecraft:iron_block;;20;74;17;NULL +minecraft:iron_block;;20;74;18;NULL +minecraft:iron_block;;20;74;19;NULL +minecraft:iron_block;;20;74;20;NULL +minecraft:red_wool;;15;64;12;NULL +minecraft:redstone_block;;15;65;12;NULL +minecraft:redstone_lamp;lit=true;15;66;12;NULL +minecraft:red_wool;;15;67;12;NULL +minecraft:red_wool;;16;64;12;NULL +minecraft:air;;16;65;12;NULL +minecraft:air;;16;66;12;NULL +minecraft:red_wool;;16;67;12;NULL +minecraft:red_wool;;17;64;12;NULL +minecraft:redstone_block;;17;65;12;NULL +minecraft:redstone_lamp;lit=true;17;66;12;NULL +minecraft:red_wool;;17;67;12;NULL +minecraft:lime_wool;;15;64;20;NULL +minecraft:redstone_block;;15;65;20;NULL +minecraft:redstone_lamp;lit=true;15;66;20;NULL +minecraft:lime_wool;;15;67;20;NULL +minecraft:lime_wool;;16;64;20;NULL +minecraft:air;;16;65;20;NULL +minecraft:air;;16;66;20;NULL +minecraft:lime_wool;;16;67;20;NULL +minecraft:lime_wool;;17;64;20;NULL +minecraft:redstone_block;;17;65;20;NULL +minecraft:redstone_lamp;lit=true;17;66;20;NULL +minecraft:lime_wool;;17;67;20;NULL +minecraft:light_blue_wool;;12;64;15;NULL +minecraft:light_blue_wool;;12;64;16;NULL +minecraft:light_blue_wool;;12;64;17;NULL +minecraft:redstone_block;;12;65;15;NULL +minecraft:air;;12;65;16;NULL +minecraft:redstone_block;;12;65;17;NULL +minecraft:redstone_lamp;lit=true;12;66;15;NULL +minecraft:air;;12;66;16;NULL +minecraft:redstone_lamp;lit=true;12;66;17;NULL +minecraft:light_blue_wool;;12;67;15;NULL +minecraft:light_blue_wool;;12;67;16;NULL +minecraft:light_blue_wool;;12;67;17;NULL +minecraft:yellow_wool;;20;64;15;NULL +minecraft:yellow_wool;;20;64;16;NULL +minecraft:yellow_wool;;20;64;17;NULL +minecraft:redstone_block;;20;65;15;NULL +minecraft:air;;20;65;16;NULL +minecraft:redstone_block;;20;65;17;NULL +minecraft:redstone_lamp;lit=true;20;66;15;NULL +minecraft:air;;20;66;16;NULL +minecraft:redstone_lamp;lit=true;20;66;17;NULL +minecraft:yellow_wool;;20;67;15;NULL +minecraft:yellow_wool;;20;67;16;NULL +minecraft:yellow_wool;;20;67;17;NULL +minecraft:oak_door;half=lower&facing=north;16;65;12;NULL +minecraft:oak_door;half=upper&facing=north;16;66;12;NULL +minecraft:oak_door;half=lower&facing=south;16;65;20;NULL +minecraft:oak_door;half=upper&facing=south;16;66;20;NULL +minecraft:oak_door;half=lower&facing=west;12;65;16;NULL +minecraft:oak_door;half=upper&facing=west;12;66;16;NULL +minecraft:oak_door;half=lower&facing=east;20;65;16;NULL +minecraft:oak_door;half=upper&facing=east;20;66;16;NULL +minecraft:wall_torch;facing=south;18;66;13;NULL +minecraft:wall_torch;facing=south;14;66;13;NULL +minecraft:wall_torch;facing=north;18;66;19;NULL +minecraft:wall_torch;facing=north;14;66;19;NULL +minecraft:wall_torch;facing=east;13;66;18;NULL +minecraft:wall_torch;facing=east;13;66;14;NULL +minecraft:wall_torch;facing=west;19;66;18;NULL +minecraft:wall_torch;facing=west;19;66;14;NULL +minecraft:oak_fence;;14;64;14;NULL +minecraft:oak_fence;;14;64;15;NULL +minecraft:oak_fence;;14;64;16;NULL +minecraft:oak_fence;;14;64;17;NULL +minecraft:oak_fence;;14;64;18;NULL +minecraft:oak_fence;;14;65;14;NULL +minecraft:air;;14;65;15;NULL +minecraft:air;;14;65;16;NULL +minecraft:air;;14;65;17;NULL +minecraft:oak_fence;;14;65;18;NULL +minecraft:oak_fence;;14;66;14;NULL +minecraft:air;;14;66;15;NULL +minecraft:air;;14;66;16;NULL +minecraft:air;;14;66;17;NULL +minecraft:oak_fence;;14;66;18;NULL +minecraft:oak_fence;;14;67;14;NULL +minecraft:air;;14;67;15;NULL +minecraft:air;;14;67;16;NULL +minecraft:air;;14;67;17;NULL +minecraft:oak_fence;;14;67;18;NULL +minecraft:oak_fence;;14;68;14;NULL +minecraft:air;;14;68;15;NULL +minecraft:air;;14;68;16;NULL +minecraft:air;;14;68;17;NULL +minecraft:oak_fence;;14;68;18;NULL +minecraft:oak_fence;;14;69;14;NULL +minecraft:air;;14;69;15;NULL +minecraft:air;;14;69;16;NULL +minecraft:air;;14;69;17;NULL +minecraft:oak_fence;;14;69;18;NULL +minecraft:oak_fence;;14;70;14;NULL +minecraft:air;;14;70;15;NULL +minecraft:air;;14;70;16;NULL +minecraft:air;;14;70;17;NULL +minecraft:oak_fence;;14;70;18;NULL +minecraft:oak_fence;;14;71;14;NULL +minecraft:air;;14;71;15;NULL +minecraft:air;;14;71;16;NULL +minecraft:air;;14;71;17;NULL +minecraft:oak_fence;;14;71;18;NULL +minecraft:oak_fence;;14;72;14;NULL +minecraft:air;;14;72;15;NULL +minecraft:air;;14;72;16;NULL +minecraft:air;;14;72;17;NULL +minecraft:oak_fence;;14;72;18;NULL +minecraft:oak_fence;;14;73;14;NULL +minecraft:air;;14;73;15;NULL +minecraft:air;;14;73;16;NULL +minecraft:air;;14;73;17;NULL +minecraft:oak_fence;;14;73;18;NULL +minecraft:oak_fence;;14;74;14;NULL +minecraft:air;;14;74;15;NULL +minecraft:air;;14;74;16;NULL +minecraft:air;;14;74;17;NULL +minecraft:oak_fence;;14;74;18;NULL +minecraft:oak_fence;;14;75;14;NULL +minecraft:oak_fence;;14;75;15;NULL +minecraft:oak_fence;;14;75;16;NULL +minecraft:oak_fence;;14;75;17;NULL +minecraft:oak_fence;;14;75;18;NULL +minecraft:oak_fence;;15;64;14;NULL +minecraft:air;;15;64;15;NULL +minecraft:air;;15;64;16;NULL +minecraft:air;;15;64;17;NULL +minecraft:oak_fence;;15;64;18;NULL +minecraft:air;;15;65;14;NULL +minecraft:air;;15;65;15;NULL +minecraft:air;;15;65;16;NULL +minecraft:stone;;15;65;17;NULL +minecraft:air;;15;65;18;NULL +minecraft:air;;15;66;14;NULL +minecraft:air;;15;66;15;NULL +minecraft:stone;;15;66;16;NULL +minecraft:air;;15;66;17;NULL +minecraft:air;;15;66;18;NULL +minecraft:air;;15;67;14;NULL +minecraft:stone;;15;67;15;NULL +minecraft:air;;15;67;16;NULL +minecraft:air;;15;67;17;NULL +minecraft:air;;15;67;18;NULL +minecraft:air;;15;68;14;NULL +minecraft:air;;15;68;15;NULL +minecraft:air;;15;68;16;NULL +minecraft:air;;15;68;17;NULL +minecraft:air;;15;68;18;NULL +minecraft:air;;15;69;14;NULL +minecraft:air;;15;69;15;NULL +minecraft:air;;15;69;16;NULL +minecraft:air;;15;69;17;NULL +minecraft:air;;15;69;18;NULL +minecraft:air;;15;70;14;NULL +minecraft:air;;15;70;15;NULL +minecraft:air;;15;70;16;NULL +minecraft:air;;15;70;17;NULL +minecraft:air;;15;70;18;NULL +minecraft:air;;15;71;14;NULL +minecraft:air;;15;71;15;NULL +minecraft:air;;15;71;16;NULL +minecraft:air;;15;71;17;NULL +minecraft:air;;15;71;18;NULL +minecraft:air;;15;72;14;NULL +minecraft:air;;15;72;15;NULL +minecraft:air;;15;72;16;NULL +minecraft:air;;15;72;17;NULL +minecraft:air;;15;72;18;NULL +minecraft:air;;15;73;14;NULL +minecraft:air;;15;73;15;NULL +minecraft:air;;15;73;16;NULL +minecraft:stone;;15;73;17;NULL +minecraft:air;;15;73;18;NULL +minecraft:air;;15;74;14;NULL +minecraft:air;;15;74;15;NULL +minecraft:stone;;15;74;16;NULL +minecraft:air;;15;74;17;NULL +minecraft:air;;15;74;18;NULL +minecraft:oak_fence;;15;75;14;NULL +minecraft:stone;;15;75;15;NULL +minecraft:air;;15;75;16;NULL +minecraft:air;;15;75;17;NULL +minecraft:oak_fence;;15;75;18;NULL +minecraft:oak_fence;;16;64;14;NULL +minecraft:air;;16;64;15;NULL +minecraft:oak_fence;;16;64;16;NULL +minecraft:stone;;16;64;17;NULL +minecraft:oak_fence;;16;64;18;NULL +minecraft:air;;16;65;14;NULL +minecraft:air;;16;65;15;NULL +minecraft:oak_fence;;16;65;16;NULL +minecraft:air;;16;65;17;NULL +minecraft:air;;16;65;18;NULL +minecraft:air;;16;66;14;NULL +minecraft:air;;16;66;15;NULL +minecraft:oak_fence;;16;66;16;NULL +minecraft:air;;16;66;17;NULL +minecraft:air;;16;66;18;NULL +minecraft:air;;16;67;14;NULL +minecraft:air;;16;67;15;NULL +minecraft:oak_fence;;16;67;16;NULL +minecraft:air;;16;67;17;NULL +minecraft:air;;16;67;18;NULL +minecraft:air;;16;68;14;NULL +minecraft:stone;;16;68;15;NULL +minecraft:oak_fence;;16;68;16;NULL +minecraft:air;;16;68;17;NULL +minecraft:air;;16;68;18;NULL +minecraft:air;;16;69;14;NULL +minecraft:air;;16;69;15;NULL +minecraft:oak_fence;;16;69;16;NULL +minecraft:air;;16;69;17;NULL +minecraft:air;;16;69;18;NULL +minecraft:air;;16;70;14;NULL +minecraft:air;;16;70;15;NULL +minecraft:oak_fence;;16;70;16;NULL +minecraft:air;;16;70;17;NULL +minecraft:air;;16;70;18;NULL +minecraft:air;;16;71;14;NULL +minecraft:air;;16;71;15;NULL +minecraft:oak_fence;;16;71;16;NULL +minecraft:air;;16;71;17;NULL +minecraft:air;;16;71;18;NULL +minecraft:air;;16;72;14;NULL +minecraft:air;;16;72;15;NULL +minecraft:oak_fence;;16;72;16;NULL +minecraft:stone;;16;72;17;NULL +minecraft:air;;16;72;18;NULL +minecraft:air;;16;73;14;NULL +minecraft:air;;16;73;15;NULL +minecraft:oak_fence;;16;73;16;NULL +minecraft:air;;16;73;17;NULL +minecraft:air;;16;73;18;NULL +minecraft:air;;16;74;14;NULL +minecraft:air;;16;74;15;NULL +minecraft:oak_fence;;16;74;16;NULL +minecraft:air;;16;74;17;NULL +minecraft:air;;16;74;18;NULL +minecraft:oak_fence;;16;75;14;NULL +minecraft:air;;16;75;15;NULL +minecraft:oak_fence;;16;75;16;NULL +minecraft:air;;16;75;17;NULL +minecraft:oak_fence;;16;75;18;NULL +minecraft:oak_fence;;17;64;14;NULL +minecraft:air;;17;64;15;NULL +minecraft:air;;17;64;16;NULL +minecraft:air;;17;64;17;NULL +minecraft:oak_fence;;17;64;18;NULL +minecraft:air;;17;65;14;NULL +minecraft:air;;17;65;15;NULL +minecraft:air;;17;65;16;NULL +minecraft:air;;17;65;17;NULL +minecraft:air;;17;65;18;NULL +minecraft:air;;17;66;14;NULL +minecraft:air;;17;66;15;NULL +minecraft:air;;17;66;16;NULL +minecraft:air;;17;66;17;NULL +minecraft:air;;17;66;18;NULL +minecraft:air;;17;67;14;NULL +minecraft:air;;17;67;15;NULL +minecraft:air;;17;67;16;NULL +minecraft:air;;17;67;17;NULL +minecraft:air;;17;67;18;NULL +minecraft:air;;17;68;14;NULL +minecraft:air;;17;68;15;NULL +minecraft:air;;17;68;16;NULL +minecraft:air;;17;68;17;NULL +minecraft:air;;17;68;18;NULL +minecraft:air;;17;69;14;NULL +minecraft:stone;;17;69;15;NULL +minecraft:air;;17;69;16;NULL +minecraft:air;;17;69;17;NULL +minecraft:air;;17;69;18;NULL +minecraft:air;;17;70;14;NULL +minecraft:air;;17;70;15;NULL +minecraft:stone;;17;70;16;NULL +minecraft:air;;17;70;17;NULL +minecraft:air;;17;70;18;NULL +minecraft:air;;17;71;14;NULL +minecraft:air;;17;71;15;NULL +minecraft:air;;17;71;16;NULL +minecraft:stone;;17;71;17;NULL +minecraft:air;;17;71;18;NULL +minecraft:air;;17;72;14;NULL +minecraft:air;;17;72;15;NULL +minecraft:air;;17;72;16;NULL +minecraft:air;;17;72;17;NULL +minecraft:air;;17;72;18;NULL +minecraft:air;;17;73;14;NULL +minecraft:air;;17;73;15;NULL +minecraft:air;;17;73;16;NULL +minecraft:air;;17;73;17;NULL +minecraft:air;;17;73;18;NULL +minecraft:air;;17;74;14;NULL +minecraft:air;;17;74;15;NULL +minecraft:air;;17;74;16;NULL +minecraft:air;;17;74;17;NULL +minecraft:air;;17;74;18;NULL +minecraft:oak_fence;;17;75;14;NULL +minecraft:air;;17;75;15;NULL +minecraft:air;;17;75;16;NULL +minecraft:air;;17;75;17;NULL +minecraft:oak_fence;;17;75;18;NULL +minecraft:oak_fence;;18;64;14;NULL +minecraft:oak_fence;;18;64;15;NULL +minecraft:oak_fence;;18;64;16;NULL +minecraft:oak_fence;;18;64;17;NULL +minecraft:oak_fence;;18;64;18;NULL +minecraft:oak_fence;;18;65;14;NULL +minecraft:air;;18;65;15;NULL +minecraft:air;;18;65;16;NULL +minecraft:air;;18;65;17;NULL +minecraft:oak_fence;;18;65;18;NULL +minecraft:oak_fence;;18;66;14;NULL +minecraft:air;;18;66;15;NULL +minecraft:air;;18;66;16;NULL +minecraft:air;;18;66;17;NULL +minecraft:oak_fence;;18;66;18;NULL +minecraft:oak_fence;;18;67;14;NULL +minecraft:air;;18;67;15;NULL +minecraft:air;;18;67;16;NULL +minecraft:air;;18;67;17;NULL +minecraft:oak_fence;;18;67;18;NULL +minecraft:oak_fence;;18;68;14;NULL +minecraft:air;;18;68;15;NULL +minecraft:air;;18;68;16;NULL +minecraft:air;;18;68;17;NULL +minecraft:oak_fence;;18;68;18;NULL +minecraft:oak_fence;;18;69;14;NULL +minecraft:air;;18;69;15;NULL +minecraft:air;;18;69;16;NULL +minecraft:air;;18;69;17;NULL +minecraft:oak_fence;;18;69;18;NULL +minecraft:oak_fence;;18;70;14;NULL +minecraft:air;;18;70;15;NULL +minecraft:air;;18;70;16;NULL +minecraft:air;;18;70;17;NULL +minecraft:oak_fence;;18;70;18;NULL +minecraft:oak_fence;;18;71;14;NULL +minecraft:air;;18;71;15;NULL +minecraft:air;;18;71;16;NULL +minecraft:air;;18;71;17;NULL +minecraft:oak_fence;;18;71;18;NULL +minecraft:oak_fence;;18;72;14;NULL +minecraft:air;;18;72;15;NULL +minecraft:air;;18;72;16;NULL +minecraft:air;;18;72;17;NULL +minecraft:oak_fence;;18;72;18;NULL +minecraft:oak_fence;;18;73;14;NULL +minecraft:air;;18;73;15;NULL +minecraft:air;;18;73;16;NULL +minecraft:air;;18;73;17;NULL +minecraft:oak_fence;;18;73;18;NULL +minecraft:oak_fence;;18;74;14;NULL +minecraft:air;;18;74;15;NULL +minecraft:air;;18;74;16;NULL +minecraft:air;;18;74;17;NULL +minecraft:oak_fence;;18;74;18;NULL +minecraft:oak_fence;;18;75;14;NULL +minecraft:oak_fence;;18;75;15;NULL +minecraft:oak_fence;;18;75;16;NULL +minecraft:oak_fence;;18;75;17;NULL +minecraft:oak_fence;;18;75;18;NULL +minecraft:wall_sign;facing=north;16;67;11;void main(String[] args) +minecraft:wall_sign;facing=south;16;67;21;void main(String[] args) +minecraft:wall_sign;facing=west;11;67;16;void main(String[] args) +minecraft:wall_sign;facing=east;21;67;16;void main(String[] args) +minecraft:wall_sign;facing=south;16;67;13;void main(String[] args) +minecraft:wall_sign;facing=north;16;67;19;void main(String[] args) +minecraft:wall_sign;facing=east;13;67;16;void main(String[] args) +minecraft:wall_sign;facing=west;19;67;16;void main(String[] args) +minecraft:wall_sign;facing=west;19;67;16;void main(String[] args) +minecraft:wall_sign;facing=west;19;67;16;First metric: 4 +minecraft:wall_sign;facing=west;19;67;17;Second metric: 0 +minecraft:wall_sign;facing=west;19;67;15;Third metric: 0 diff --git a/sources/test/testing/rendering/world/level.dat b/sources/test/testing/rendering/world/level.dat new file mode 100644 index 00000000..36bdbfeb Binary files /dev/null and b/sources/test/testing/rendering/world/level.dat differ diff --git a/sources/test/testing/rendering/world/region/r.0.0.mca b/sources/test/testing/rendering/world/region/r.0.0.mca new file mode 100644 index 00000000..f8ffc51c Binary files /dev/null and b/sources/test/testing/rendering/world/region/r.0.0.mca differ diff --git a/sources/toolchain/converter/.project b/sources/toolchain/converter/.project index 6d3ab881..d1d17cec 100644 --- a/sources/toolchain/converter/.project +++ b/sources/toolchain/converter/.project @@ -1,23 +1,20 @@ - codemetropolis-toolchain-converter - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - + codemetropolis-toolchain-converter + NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. + + codemetropolis-toolchain-commons + + + + org.eclipse.jdt.core.javabuilder + + + org.eclipse.m2e.core.maven2Builder + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + diff --git a/sources/toolchain/converter/pom.xml b/sources/toolchain/converter/pom.xml index 2600b699..1a2537a5 100644 --- a/sources/toolchain/converter/pom.xml +++ b/sources/toolchain/converter/pom.xml @@ -42,12 +42,45 @@ args4j args4j - 2.32 sed graphlib - 1.0 + + + org.junit.jupiter + junit-jupiter-api + + + + junit + junit + test + + + org.gitlab4j + gitlab4j-api + 4.9.19 + + + + + args4j + args4j + 2.32 + + + sed + graphlib + 1.0 + + + ${project.groupId} + commons + 1.4.0 + + + diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/Main.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/Main.java index ccd3b65f..8773c94a 100644 --- a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/Main.java +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/Main.java @@ -2,7 +2,6 @@ import java.util.HashMap; import java.util.Map; - import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/control/ConverterLoader.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/control/ConverterLoader.java index 39579620..d20d1e22 100644 --- a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/control/ConverterLoader.java +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/control/ConverterLoader.java @@ -1,10 +1,12 @@ package codemetropolis.toolchain.converter.control; import java.util.Map; - +import codemetropolis.toolchain.converter.gitstat.GitStatConverter; +import codemetropolis.toolchain.converter.gitlab.GitLabConverter; import codemetropolis.toolchain.commons.cdf.converter.CdfConverter; import codemetropolis.toolchain.converter.sonarqube.SonarQubeConverter; import codemetropolis.toolchain.converter.sourcemeter.GraphConverter; +import codemetropolis.toolchain.converter.pmd.PmdConverter; public class ConverterLoader { @@ -12,10 +14,16 @@ private ConverterLoader() {} public static CdfConverter load(ConverterType converterType, Map params) { switch(converterType) { + case GITLAB: + return new GitLabConverter(params); + case GITSTATS: + return new GitStatConverter(params); case SOURCEMETER: return new GraphConverter(params); case SONARQUBE: return new SonarQubeConverter(params); + case PMD: + return new PmdConverter(params); default: return null; } diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/control/ConverterType.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/control/ConverterType.java index da4a69ad..94e68992 100644 --- a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/control/ConverterType.java +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/control/ConverterType.java @@ -1,6 +1,9 @@ package codemetropolis.toolchain.converter.control; public enum ConverterType { + GITLAB, + GITSTATS, SOURCEMETER, - SONARQUBE + SONARQUBE, + PMD } diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabClient.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabClient.java new file mode 100644 index 00000000..734aa07b --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabClient.java @@ -0,0 +1,38 @@ +package codemetropolis.toolchain.converter.gitlab; + +import org.gitlab4j.api.*; + +public class GitLabClient { + + private final String EXCEPTION_MESSAGE = "Invalid project, group, username or password! (-i hostUrl (eg.: http://gitlab-okt.sed.hu) parameters are: -p username=... password=... group=... project=...)"; + + private String hostUrl; + private String username; + private String password; + + public GitLabClient(String hostUrl, String username, String password) { + this.hostUrl = hostUrl; + this.username = username; + this.password = password; + } + + public String getHostUrl() { + return hostUrl; + } + + @SuppressWarnings("deprecation") + public void authentication() throws GitLabConnectException + { + GitLabApi gitLabApi = null; + + try { + gitLabApi = GitLabApi.login(hostUrl, username, password); + } catch (GitLabApiException e) { + throw new GitLabConnectException(EXCEPTION_MESSAGE); + } + + if(gitLabApi != null) { + GitLabElement.setGitLabApi(gitLabApi); + } + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabConnectException.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabConnectException.java new file mode 100644 index 00000000..e4688490 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabConnectException.java @@ -0,0 +1,8 @@ +package codemetropolis.toolchain.converter.gitlab; + +import codemetropolis.toolchain.commons.exceptions.CodeMetropolisException; + +public class GitLabConnectException extends CodeMetropolisException { + public GitLabConnectException() { super(); } + public GitLabConnectException(String message) { super(message); } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabConverter.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabConverter.java new file mode 100644 index 00000000..b5933627 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabConverter.java @@ -0,0 +1,116 @@ +package codemetropolis.toolchain.converter.gitlab; + +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.commons.cdf.CdfTree; +import codemetropolis.toolchain.commons.cdf.converter.CdfConverter; +import codemetropolis.toolchain.commons.exceptions.CodeMetropolisException; +import org.gitlab4j.api.GitLabApiException; +import org.gitlab4j.api.models.Project; + +import java.util.List; +import java.util.Map; + +//to run: -t gitlab -i hostUrl (e.g.: http://gitlab-okt.sed.hu) -o output_dir -p username= password= group= project= projectID= + +public class GitLabConverter extends CdfConverter { + + public final String USER_NAME_PARAM = "username"; + public final String PASSWORD_PARAM = "password"; + public final String GROUP_PARAM = "group"; + public final String PROJECT_PARAM = "project"; + public final String PROJECT_ID = "projectID"; + + private String hostUrl; + private String projectName; + private String groupName; + + private Project p; + + public String getHostUrl() { + return hostUrl; + } + + public void setHostUrl(String hostUrl) { + this.hostUrl = hostUrl; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public Project getP() { + return p; + } + + public void setP(Project p) { + this.p = p; + } + + public String createFullUrl() { + return hostUrl + "/" + groupName + "/" + projectName; + } + + public GitLabConverter() {super(null);} + + public GitLabConverter(Map params) { + super(params); + } + + public void authentication() throws GitLabConnectException + { + projectName = getParameter(PROJECT_PARAM); + groupName = getParameter(GROUP_PARAM); + + GitLabClient glc = new GitLabClient(hostUrl, getParameter(USER_NAME_PARAM), getParameter(PASSWORD_PARAM)); + glc.authentication(); + } + + @Override + public CdfTree createElements(String source) throws CodeMetropolisException { + hostUrl = source; + + try { + authentication(); + + List pList; + pList = GitLabElement.gitLabApi.getProjectApi().getProjects(); + + for(Project pr : pList) + { + if(pr.getId().equals(Integer.parseInt(getParameter(PROJECT_ID)))) { + p = pr; + GitLabElement.setProjectID(p.getId()); + } + } + } catch (GitLabConnectException e) { + throw new CodeMetropolisException(e.getMessage()); + } catch (GitLabApiException e) { + throw new CodeMetropolisException(e.getMessage()); + } + + CdfTree tree = new CdfTree(); + CdfElement root = null; + + try { + root = GitLabResource.getElement(Type.PROJECT, Integer.toString(GitLabElement.projectId), Integer.toString(GitLabElement.projectId)); + } catch (GitLabException e) { + throw new CodeMetropolisException(e.getMessage()); + } + + tree.setRoot(root); + + return tree; + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabElement.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabElement.java new file mode 100644 index 00000000..ab1ecae8 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabElement.java @@ -0,0 +1,105 @@ +package codemetropolis.toolchain.converter.gitlab; + +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import org.gitlab4j.api.GitLabApi; + +import java.util.ArrayList; +import java.util.List; + +public abstract class GitLabElement { + + private List properties; + protected List children; + private List parentIds; + + protected static Integer projectId; + protected static GitLabApi gitLabApi; + + protected Type type; + protected String ID; + + public String getID() { + return ID; + } + + protected CdfElement element; + + public List getParentIds() { + return parentIds; + } + + public void addChild(Pair child) { + children.add(child); + } + + public static void setProjectID(int project) { + projectId = project; + } + + public static void setGitLabApi(GitLabApi gitLabA) { + gitLabApi = gitLabA; + } + + public void addParentID(String parentId) { + parentIds.add(parentId); + } + + public GitLabElement() { + this.parentIds=new ArrayList<>(); + this.children=new ArrayList<>(); + } + + public void makeProperties() { + properties = createProperties(); + } + + public void makeChildren() { + children = createChildren(); + } + + private String currParentId; + + public CdfElement getElement() throws GitLabException { + + if (GitLabResource.consistsOf(type, ID)) { + GitLabResource.addParentID(type, ID, currParentId); + return GitLabResource.getElement(type, ID).element; + } + + CdfElement element = new CdfElement(ID, type.toString().toLowerCase()); + makeChildren(); + + for(Pair ch: children) { + GitLabElement el=GitLabResource.receiveElement(ch.getType()); + el.addParentID(ID); + el.currParentId=ID; + el.setID(ch.getID()); + el.setType(ch.getType()); + element.addChildElement(el.getElement()); + } + + makeProperties(); + + for (CdfProperty property : properties) { + element.addProperty(property.getName(), property.getValue(), property.getType()); + } + + + this.element=element; + GitLabResource.addElement(this); + + return element; + } + + public void setID(String id) { + this.ID = id; + } + + public void setType(Type type) {this.type = type;} + + public abstract List createProperties(); + + public abstract List createChildren(); + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabException.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabException.java new file mode 100644 index 00000000..347cd19f --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabException.java @@ -0,0 +1,23 @@ +package codemetropolis.toolchain.converter.gitlab; + +public class GitLabException extends Exception{ + public GitLabException() { + super(); + } + + public GitLabException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public GitLabException(String message, Throwable cause) { + super(message, cause); + } + + public GitLabException(String message) { + super(message); + } + + public GitLabException(Throwable cause) { + super(cause); + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabResource.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabResource.java new file mode 100644 index 00000000..701326b0 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/GitLabResource.java @@ -0,0 +1,125 @@ +package codemetropolis.toolchain.converter.gitlab; + +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.converter.gitlab.model.*; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +public class GitLabResource { + + private static Map> mainStorage = new EnumMap>(Type.class); + + public static GitLabElement receiveElement(Type t) throws GitLabException { + switch(t) { + case PROJECT: + return new Project(); + case COMMIT: + return new Commit(); + case TREE: + return new Tree(); + case ISSUE: + return new Issue(); + case BRANCH: + return new Branch(); + case MILESTONE: + return new Milestone(); + case USER: + return new User(); + default: + throw new GitLabException("Illegal type"); + } + + } + + public static void clearMainStorage() {mainStorage.clear();} + + public static Map> getMainStorage() { + return mainStorage; + } + + public static boolean consistsOf(Type type, String ID) { + return mainStorage.containsKey(type) && mainStorage.get(type).containsKey(ID); + } + + public static boolean addElement(GitLabElement element) { + if (mainStorage.containsKey(element.type)) { + if (mainStorage.get(element.type).containsKey(element.ID)) + return false; + + mainStorage.get(element.type).put(element.ID, element); + + return true; + } + + mainStorage.put(element.type, new HashMap<>()); + mainStorage.get(element.type).put(element.ID, element); + + return true; + } + + public static void addParentID(Type type, String ID, String parentID) { + if (consistsOf(type, ID)) { + GitLabElement element=mainStorage.get(type).get(ID); + element.addParentID(parentID); + mainStorage.get(type).put(ID, element); + } + } + + public static Map getAllByType(Type type) { + return mainStorage.get(type); + } + + public static GitLabElement getElement(Type type, String ID) { + return mainStorage.get(type).get(ID); + } + + public static GitLabElement getElement(Pair pair) { + return getElement(pair.getType(), pair.getID()); + } + + public static CdfElement getElement(Type type, String ID, String parentId) throws GitLabException { + if (ID==null) return new CdfElement(); + + try { + if (mainStorage.containsKey(type)) { + if (mainStorage.get(type).containsKey(ID)) + return mainStorage.get(type).get(ID).element; + + GitLabElement gle = createGitLabElement(type, ID, parentId); + mainStorage.get(type).put(ID, gle); + + return gle.element; + } + + Map m=new HashMap<>(); + GitLabElement gle = createGitLabElement(type, ID, parentId); + + CdfElement out=gle.getElement(); + m.put(ID, gle); + + mainStorage.put(type, m); + + return out; + } catch (Exception e) { + System.out.println("ID: " + ID); + System.out.println("Type: " + type); + + System.out.println("Parent ID: " + parentId); + throw new GitLabException("Illegal argument added"); + } + + } + + private static GitLabElement createGitLabElement(Type type, String ID, String parentId) throws GitLabException { + GitLabElement gle = receiveElement(type); + gle.addParentID(parentId); + gle.setType(type); + gle.setID(ID); + gle.makeProperties(); + + return gle; + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/Pair.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/Pair.java new file mode 100644 index 00000000..4856aeeb --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/Pair.java @@ -0,0 +1,19 @@ +package codemetropolis.toolchain.converter.gitlab; + +public class Pair { + private String ID; + private Type type; + + public Pair(String ID, Type type) { + this.ID = ID; + this.type = type; + } + + public String getID() { + return ID; + } + + public Type getType() { + return type; + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/Type.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/Type.java new file mode 100644 index 00000000..1c98e994 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/Type.java @@ -0,0 +1,5 @@ +package codemetropolis.toolchain.converter.gitlab; + +public enum Type { + BRANCH, PROJECT, ISSUE, USER, COMMIT, TREE, MILESTONE +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Branch.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Branch.java new file mode 100644 index 00000000..e4f55470 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Branch.java @@ -0,0 +1,118 @@ +package codemetropolis.toolchain.converter.gitlab.model; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.GitLabElement; +import codemetropolis.toolchain.converter.gitlab.GitLabResource; +import codemetropolis.toolchain.converter.gitlab.Pair; +import codemetropolis.toolchain.converter.gitlab.Type; +import org.gitlab4j.api.*; +import org.gitlab4j.api.models.Commit; +import org.gitlab4j.api.models.TreeItem; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +public class Branch extends GitLabElement { + private String name; + + private int isMerged; + private int developersCanPush; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getIsMerged() { + return isMerged; + } + + public void setIsMerged(int isMerged) { + this.isMerged = isMerged; + } + + public int getDevelopersCanPush() { + return developersCanPush; + } + + public void setDevelopersCanPush(int developersCanPush) { + this.developersCanPush = developersCanPush; + } + + public static int convertBooleanToInteger(boolean value) { + if (value == true) + return 1; + else + return 0; + } + + public void addProperties(List list) { + list.add(new CdfProperty("isMerged", isMerged + "", CdfProperty.Type.INT)); + list.add(new CdfProperty("developersCanPush", developersCanPush + "", CdfProperty.Type.INT)); + } + + @Override + public List createProperties() { + RepositoryApi rapi = new RepositoryApi(gitLabApi); + List list = new ArrayList<>(); + + try { + org.gitlab4j.api.models.Branch b = rapi.getBranch(projectId, ID); + + name = b.getName(); + + isMerged = convertBooleanToInteger(b.getMerged()); + developersCanPush = convertBooleanToInteger(b.getDevelopersCanPush()); + addProperties(list); + + } catch (GitLabApiException e) { + e.printStackTrace(); + } + + return list; + } + + @Override + public List createChildren() { + RepositoryApi rapi = new RepositoryApi(gitLabApi); + Pair child; + List list = new ArrayList<>(); + List items = null; + org.gitlab4j.api.models.Branch b=null; + + try { + items = rapi.getTree(projectId); + b = rapi.getBranch(projectId, ID); + + Queue commits = new LinkedList<>(); + commits.add(b.getCommit()); + CommitsApi capi=gitLabApi.getCommitsApi(); + + while(!commits.isEmpty()) { + Commit commit=commits.remove(); + list.add(new Pair(commit.getId(), Type.COMMIT)); + + for(String commit1: commit.getParentIds()) { + if (!GitLabResource.consistsOf(Type.COMMIT, commit1)) + commits.add(capi.getCommit(projectId, commit1)); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + for(TreeItem item: items) { + if(item.getType() == TreeItem.Type.TREE) { + child = new Pair(item.getPath()+"---"+ID, Type.TREE); + list.add(child); + } + } + + return list; + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Commit.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Commit.java new file mode 100644 index 00000000..50498e93 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Commit.java @@ -0,0 +1,90 @@ +package codemetropolis.toolchain.converter.gitlab.model; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.GitLabElement; +import codemetropolis.toolchain.converter.gitlab.Pair; +import org.gitlab4j.api.CommitsApi; +import org.gitlab4j.api.GitLabApiException; + +import java.util.ArrayList; +import java.util.List; + +public class Commit extends GitLabElement { + private int messageLength; + private int addition; + private int deletions; + private int total; + private int numberOfComments; + + private String status; + private String message; + + public void setTotal(int total) { + this.total = total; + } + + public void setStatus(String status) { + this.status = status; + } + + public void setDeletions(int deletions) { + this.deletions = deletions; + } + + public void setAddition(int addition) { + this.addition = addition; + } + + public void setMessage(String message) { + this.message = message; + } + + public void setNumberOfComments(int numberOfComments) { + this.numberOfComments = numberOfComments; + } + + @Override + public List createProperties() { + CommitsApi capi = new CommitsApi(gitLabApi); + List list = new ArrayList<>(); + org.gitlab4j.api.models.Commit c=null; + + try { + c= capi.getCommit(projectId, ID); + if (c!=null) { + message=c.getMessage(); + addition = c.getStats().getAdditions(); + deletions = c.getStats().getDeletions(); + total = c.getStats().getTotal(); + status = c.getStatus(); + numberOfComments = capi.getComments(projectId, ID).size(); + } + } catch (GitLabApiException e) { + //e.printStackTrace(); + } + catch (Exception e) { + e.printStackTrace(); + } + + if (message!=null) + messageLength=message.length(); + if (ID!=null) { + list.add(new CdfProperty("messageLength", Integer.toString(messageLength), CdfProperty.Type.INT)); + list.add(new CdfProperty("addition", Integer.toString(addition), CdfProperty.Type.INT)); + list.add(new CdfProperty("deletion", Integer.toString(deletions), CdfProperty.Type.INT)); + list.add(new CdfProperty("total", Integer.toString(total), CdfProperty.Type.INT)); + list.add(new CdfProperty("status", status, CdfProperty.Type.STRING)); + list.add(new CdfProperty("numberOfComments", numberOfComments + "", CdfProperty.Type.INT)); + list.add(new CdfProperty("message", message, CdfProperty.Type.STRING)); + } + + return list; + } + + @Override + public List createChildren() { + List list=new ArrayList<>(); + + return list; + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Issue.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Issue.java new file mode 100644 index 00000000..4200d796 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Issue.java @@ -0,0 +1,105 @@ +package codemetropolis.toolchain.converter.gitlab.model; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.GitLabElement; +import codemetropolis.toolchain.converter.gitlab.Pair; +import org.gitlab4j.api.IssuesApi; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class Issue extends GitLabElement { + + private String state; + + private int userNotesCount; + private int weight; + private int timeEstimate; + private int totalTime; + + private float timeRatio; + + public void setState(String state) { + this.state = state; + } + + public void setTimeRatio(float timeRatio) { + this.timeRatio = timeRatio; + } + + public void setTimeEstimate(int timeEstimate) { + this.timeEstimate = timeEstimate; + } + + public void setTotalTime(int totalTime) { + this.totalTime = totalTime; + } + + public void setUserNotesCount(int userNotesCount) { + this.userNotesCount = userNotesCount; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + @Override + public List createProperties() { + + List properties=new ArrayList<>(); + + if (ID==null) return properties; + + IssuesApi iapi=null; + + if (gitLabApi!=null) + iapi=new IssuesApi(gitLabApi); + + org.gitlab4j.api.models.Issue issue=null; + + if (iapi!=null) { + Optional opt = iapi.getOptionalIssue(projectId, Integer.parseInt(ID)); + issue = opt.orElse(null); + } + + if (issue!=null && issue.getId()!=null) { + if (issue.getState()!=null) + state = issue.getState().toString(); + + if (issue.getUserNotesCount()!=null) + userNotesCount = issue.getUserNotesCount(); + + if (issue.getWeight()!=null) + weight = issue.getWeight(); + + if (issue.getTimeStats()!=null) { + timeEstimate = issue.getTimeStats().getTimeEstimate(); + totalTime = issue.getTimeStats().getTimeEstimate(); + } + } + + if (totalTime==0) + timeRatio=0; + else + timeRatio = (float) (timeEstimate / (float) totalTime); + + if (state!=null) + properties.add(new CdfProperty("state", state, CdfProperty.Type.STRING)); + + properties.add(new CdfProperty("userNoteCount", Integer.toString(userNotesCount), CdfProperty.Type.INT)); + properties.add(new CdfProperty("weight", Integer.toString(weight), CdfProperty.Type.INT)); + properties.add(new CdfProperty("timeEstimate", Integer.toString(timeEstimate), CdfProperty.Type.INT)); + properties.add(new CdfProperty("totalTime", Integer.toString(totalTime), CdfProperty.Type.INT)); + properties.add(new CdfProperty("timeRatio", Float.toString(timeRatio), CdfProperty.Type.FLOAT)); + + return properties; + } + + @Override + public List createChildren() { + List children=new ArrayList<>(); + + return children; + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Milestone.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Milestone.java new file mode 100644 index 00000000..8a7fe1c3 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Milestone.java @@ -0,0 +1,100 @@ +package codemetropolis.toolchain.converter.gitlab.model; + +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.*; +import org.gitlab4j.api.GitLabApiException; +import org.gitlab4j.api.MilestonesApi; +import org.gitlab4j.api.models.Issue; + +import java.util.ArrayList; +import java.util.List; + + +public class Milestone extends GitLabElement { + + private String title; + private String state; + + private double closedRatio; + private double openedRatio; + + public void setTitle(String title) { + this.title = title; + } + + public void setState(String state) { + this.state = state; + } + + @Override + public List createProperties() { + MilestonesApi mapi=null; + + if (gitLabApi!=null) + mapi=new MilestonesApi(gitLabApi); + + List properties=new ArrayList<>(); + + double all=children.size(); + + try { + org.gitlab4j.api.models.Milestone milestone=null; + if (mapi!=null) + milestone=mapi.getMilestone(projectId, Integer.parseInt(ID)); + + if (milestone!=null) { + title = milestone.getTitle(); + state = milestone.getState(); + } + + if (ID!=null) { + properties.add(new CdfProperty("title", title, CdfProperty.Type.STRING)); + properties.add(new CdfProperty("state", state, CdfProperty.Type.STRING)); + + for (Pair child : children) { + CdfElement element = GitLabResource.getElement(child).getElement(); + if (element.getPropertyValue("state").equals("closed")) closedRatio++; + else openedRatio++; + } + } + + } catch (GitLabApiException e) { + e.printStackTrace(); + } catch (GitLabException e) { + e.printStackTrace(); + } + + if (all!=0.0) { + closedRatio/=all; + openedRatio/=all; + } + + if (ID!=null) { + properties.add(new CdfProperty("closedRatio", closedRatio + "", CdfProperty.Type.FLOAT)); + properties.add(new CdfProperty("openedRatio", openedRatio + "", CdfProperty.Type.FLOAT)); + } + + return properties; + } + + @Override + public List createChildren() { + if (ID==null) return new ArrayList<>(); + + MilestonesApi mapi=new MilestonesApi(gitLabApi); + List children=new ArrayList<>(); + + try { + List issues=mapi.getIssues(projectId, Integer.parseInt(ID)); + for(Issue issue: issues) { + children.add(new Pair(issue.getIid().toString(), Type.ISSUE)); + } + + } catch (GitLabApiException e) { + e.printStackTrace(); + } + + return children; + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Project.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Project.java new file mode 100644 index 00000000..7d57d370 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Project.java @@ -0,0 +1,178 @@ +package codemetropolis.toolchain.converter.gitlab.model; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.GitLabElement; +import codemetropolis.toolchain.converter.gitlab.Pair; +import codemetropolis.toolchain.converter.gitlab.Type; +import org.gitlab4j.api.*; +import org.gitlab4j.api.models.*; +import java.util.*; + +public class Project extends GitLabElement { + + private String name; + + private int commitCount; + private int jobArtifactsSize; + private int lfsObjectSize; + private int storageSize; + private int approvalsNumber = 0; + private int forksCount = 0; + + public Project() {} + + public int getCommitCount() { + return commitCount; + } + + public void setCommitCount(int commitCount) { + this.commitCount = commitCount; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getJobArtifactsSize() { + return jobArtifactsSize; + } + + public void setJobArtifactsSize(int jobArtifactsSize) { + this.jobArtifactsSize = jobArtifactsSize; + } + + public int getLfsObjectSize() { + return lfsObjectSize; + } + + public void setLfsObjectSize(int lfsObjectSize) { + this.lfsObjectSize = lfsObjectSize; + } + + public int getStorageSize() { + return storageSize; + } + + public void setStorageSize(int storageSize) { + this.storageSize = storageSize; + } + + public int getApprovalsNumber() { + return approvalsNumber; + } + + public void setApprovalsNumber(int approvalsNumber) { + this.approvalsNumber = approvalsNumber; + } + + public int getForksCount() { + return forksCount; + } + + public void setForksCount(int forksCount) { + this.forksCount = forksCount; + } + private class BranchHolder implements Comparable { + String branchName; + + Date commitDate; + + public BranchHolder(String branchName, Date commitDate) { + this.branchName=branchName; + this.commitDate=commitDate; + } + @Override + public int compareTo(Object o) { + return this.commitDate.compareTo(((BranchHolder)o).commitDate); + } + + } + + public void addProperties(List properties) { + properties.add(new CdfProperty("commitCount", Integer.toString(commitCount), CdfProperty.Type.INT)); + properties.add(new CdfProperty("jobArtifactsSize", Integer.toString(jobArtifactsSize), CdfProperty.Type.INT)); + properties.add(new CdfProperty("lfsObjectSize", Integer.toString(lfsObjectSize), CdfProperty.Type.INT)); + properties.add(new CdfProperty("storageSize", Integer.toString(storageSize), CdfProperty.Type.INT)); + properties.add(new CdfProperty("approvalsNumber", Integer.toString(approvalsNumber), CdfProperty.Type.INT)); + properties.add(new CdfProperty("forksCount", Integer.toString(forksCount), CdfProperty.Type.INT)); + properties.add(new CdfProperty("name", name, CdfProperty.Type.STRING)); + } + + @Override + public List createProperties() { + + List properties = new ArrayList<>(); + + if(gitLabApi != null) { + ProjectApi papi = new ProjectApi(gitLabApi); + + try { + org.gitlab4j.api.models.Project proj = papi.getProject(ID, true); + ProjectStatistics projectStatistics = proj.getStatistics(); + + if (proj.getApprovalsBeforeMerge() != null) + approvalsNumber=proj.getApprovalsBeforeMerge(); + + name = proj.getName(); + + if (proj.getForksCount() != null) + forksCount=proj.getForksCount(); + + storageSize = (int) projectStatistics.getStorageSize(); + lfsObjectSize = (int) projectStatistics.getLfsObjectSize(); + jobArtifactsSize = (int) projectStatistics.getJobArtifactsSize(); + commitCount = (int) projectStatistics.getCommitCount(); + + addProperties(properties); + + } catch (GitLabApiException e) { + e.printStackTrace(); + } + } + + return properties; + } + + @Override + public List createChildren() { + List children = new ArrayList<>(); + + if(gitLabApi != null) { + try { + MilestonesApi mapi = gitLabApi.getMilestonesApi(); + List milestoneList = mapi.getMilestones(Integer.parseInt(ID)); + + for (org.gitlab4j.api.models.Milestone milestone: milestoneList) { + children.add(new Pair(milestone.getId().toString(), Type.MILESTONE)); + } + + RepositoryApi rapi=new RepositoryApi(gitLabApi); + + List branches=rapi.getBranches(Integer.parseInt(ID)); + + Set holders=new TreeSet<>(); + + for(org.gitlab4j.api.models.Branch branch: branches) { + holders.add(new BranchHolder(branch.getName(), branch.getCommit().getCommittedDate())); + } + + for(BranchHolder holder: holders) { + children.add(new Pair(holder.branchName, Type.BRANCH)); + } + + for(Contributor contributor: rapi.getContributors(Integer.parseInt(ID))) { + children.add(new Pair(contributor.getEmail(), Type.USER)); + } + } catch (GitLabApiException e) { + e.printStackTrace(); + } + + } + + return children; + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Tree.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Tree.java new file mode 100644 index 00000000..e2dc399a --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/Tree.java @@ -0,0 +1,82 @@ +package codemetropolis.toolchain.converter.gitlab.model; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.GitLabElement; +import codemetropolis.toolchain.converter.gitlab.Pair; +import codemetropolis.toolchain.converter.gitlab.Type; +import org.gitlab4j.api.GitLabApiException; +import org.gitlab4j.api.RepositoryApi; +import org.gitlab4j.api.models.TreeItem; +import java.util.ArrayList; +import java.util.List; + +public class Tree extends GitLabElement { + + private int numberOfChildren; + + private String branchName; + private String name; + + public String getBranchName() { + return branchName; + } + public String getName() { + return name; + } + + @Override + public List createProperties() { + List properties=new ArrayList<>(); + + if (ID==null) return properties; + + RepositoryApi repository=null; + + if (gitLabApi!=null) { + repository=new RepositoryApi(gitLabApi); + } + + String names[] = ID.split("---"); + branchName = names[names.length-1]; + name=names[0]; + + if (repository!=null) { + try { + List list = repository.getTree(projectId, name, branchName, true); + numberOfChildren = list.size(); + } catch (GitLabApiException e) { + e.printStackTrace(); + } + } + + properties.add(new CdfProperty("numberOfChildren", numberOfChildren + "", CdfProperty.Type.INT)); + + return properties; + } + + @Override + public List createChildren() { + if (ID==null) return new ArrayList<>(); + RepositoryApi repository=new RepositoryApi(gitLabApi); + String names[] = ID.split("---"); + String branchName = names[names.length-1]; + List out=new ArrayList<>(); + String name=names[0]; + + try { + List list=repository.getTree(projectId, name, branchName); + + for(TreeItem treeItem: list) { + if (treeItem.getType()==TreeItem.Type.TREE) { + out.add(new Pair(treeItem.getPath()+"---"+branchName, Type.TREE)); + } + + } + } catch (GitLabApiException e) { + e.printStackTrace(); + } + + + return out; + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/User.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/User.java new file mode 100644 index 00000000..e1d01932 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitlab/model/User.java @@ -0,0 +1,115 @@ +package codemetropolis.toolchain.converter.gitlab.model; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.GitLabElement; +import codemetropolis.toolchain.converter.gitlab.GitLabResource; +import codemetropolis.toolchain.converter.gitlab.Pair; +import codemetropolis.toolchain.converter.gitlab.Type; +import org.gitlab4j.api.*; +import org.gitlab4j.api.models.Commit; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class User extends GitLabElement { + private String username; + + private int isAdmin; + private int commitNumber; + private int deletions; + private int additions; + private int total; + + private float deletionRatio; + private float addingRatio; + + public User() {} + + public float getDeletionRatio() { + return deletionRatio; + } + public float getAddingRatio() { return addingRatio; } + + public void setDeletionRatio(int deletion, int total) { + if (total == 0) + deletionRatio = 0.0f; + else + deletionRatio = ((float)deletion / (float)total); + } + + public void setAddingRatio(int additions, int total) { + if(total == 0) + addingRatio = 0.0f; + else + addingRatio = ((float)additions/ (float)total); + } + + @Override + public List createProperties() { + List list = new ArrayList<>(); + UserApi uapi = gitLabApi.getUserApi(); + //RepositoryApi rapi=gitLabApi.getRepositoryApi(); + + commitNumber=0; + additions=0; + deletions=0; + + try { + List currentUsers = uapi.findUsers(ID); + + Map typeCommit=GitLabResource.getAllByType(Type.COMMIT); + CommitsApi commitsApi=gitLabApi.getCommitsApi(); + + for(GitLabElement gle: typeCommit.values()) { + Commit commit=commitsApi.getCommit(projectId, gle.getID()); + + if ( commit.getCommitterEmail().equals(ID)) { + commitNumber++; + additions+=commit.getStats().getAdditions(); + deletions+=commit.getStats().getDeletions(); + } + + } + + total = deletions + additions; + + if (currentUsers.size()>0) { + org.gitlab4j.api.models.User currentUser = currentUsers.get(0); + //List attributeLIst = currentUser.getCustomAttributes(); + + username = currentUser.getUsername(); + Boolean admin = currentUser.getIsAdmin(); + + if (admin != null && currentUser.getIsAdmin()) { + isAdmin = 1; + } else { + isAdmin = 0; + } + + list.add(new CdfProperty("username", username, CdfProperty.Type.STRING)); + list.add(new CdfProperty("admin", isAdmin + "", CdfProperty.Type.INT)); + } + + setDeletionRatio(deletions, total); + setAddingRatio(additions, total); + + list.add(new CdfProperty("numberOfCommits", commitNumber + "", CdfProperty.Type.INT)); + list.add(new CdfProperty("deletions", deletions + "", CdfProperty.Type.INT)); + list.add(new CdfProperty("additions", additions + "", CdfProperty.Type.INT)); + list.add(new CdfProperty("deletionRatio", deletionRatio + "", CdfProperty.Type.FLOAT)); + list.add(new CdfProperty("additionRatio", addingRatio + "", CdfProperty.Type.FLOAT)); + + } catch (GitLabApiException e) { + e.printStackTrace(); + } + + return list; + } + + @Override + public List createChildren() { + List list = new ArrayList<>(); + + return list; + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/CdfTreeBuilder.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/CdfTreeBuilder.java new file mode 100644 index 00000000..c5248ba2 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/CdfTreeBuilder.java @@ -0,0 +1,127 @@ +package codemetropolis.toolchain.converter.gitstat; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.commons.cdf.CdfTree; + +public class CdfTreeBuilder { + + public static CdfTree createTreeFromMap( Map> map ) { + CdfTree tree = new CdfTree(); + if ( map != null) { + map.keySet() + .stream() + .forEachOrdered(element->addPropertiesToElement(element, map.get(element), tree)); + } + return tree; + } + + public static void addPropertiesToElement(CdfElement element, + List list, CdfTree tree) { + list.stream() + .forEachOrdered(p->addPropertyToElement(element, p, tree)); + } + + public static void addPropertyToElement(CdfElement element, CdfProperty p, CdfTree tree) { + if ( element != null && p != null && tree !=null) { + element.addProperty(p.getName(), p.getValue(), p.getType()); + if ( tree.getRoot() == null) { + tree.setRoot(element); + } else { + tree.getRoot().addChildElement(element); + } + } + } + + public static CdfTree createTree(CdfElement element, List properties) { + + CdfTree tree = new CdfTree(); + Map rowElementMap = new HashMap<>(); + Map dateStatisticsMap = new HashMap<>(); + List otherProperties = new ArrayList<>(); + + for (CdfProperty property : properties) { + String propertyName = property.getName(); + if (propertyName.endsWith("Extension")) { + propertyName = (propertyName.substring(0, propertyName.length() - "Extension".length())); + String rowNumber = propertyName.substring( + propertyName.indexOf("Row") + "Row".length(), propertyName.length() - 1); + System.out.println("rownumber = " +rowNumber); + rowElementMap.put("Row_" + rowNumber, new CdfElement(property.getValue(), "Extension")); + } else if (propertyName.contains("Extensions")) { + String suffix = propertyName.substring(propertyName.lastIndexOf('_') + 1, + propertyName.lastIndexOf(' ') == -1 ? propertyName.length() : propertyName.lastIndexOf(' ') ); + System.out.println("suffix: " + suffix); + propertyName = (propertyName.substring(0, propertyName.indexOf(suffix) - 1)); + System.out.println("propertyName: " + propertyName); + String rowNumber = propertyName.substring( + propertyName.indexOf("Row") + "Row".length(), propertyName.length()); + String key = "Row_" + rowNumber; + System.out.println("key " + key); + if ( rowElementMap.containsKey(key) ) { + System.out.println("FOUND!"); + rowElementMap.get(key).addProperty(suffix, property.getValue().substring( + 0, property.getValue().lastIndexOf(' ') == -1 ? property.getValue().length() : property.getValue().lastIndexOf(' ')), CdfProperty.Type.INT); + } + } else if ( propertyName.contains("commits by year") ) { + if (!dateStatisticsMap.containsKey("commits by year")) { + dateStatisticsMap.put("commits by year", new CdfElement("commits by year", "statistics")); + } + dateStatisticsMap.get("commits by year").addProperty(propertyName.substring("commits by year".length()), property.getValue(), CdfProperty.Type.INT); + } else if ( propertyName.contains("day of week") ) { + if (!dateStatisticsMap.containsKey("day of week")) { + dateStatisticsMap.put("day of week", new CdfElement("day of week", "statistics")); + } + dateStatisticsMap.get("day of week").addProperty(propertyName.substring("day of week".length()), property.getValue(), CdfProperty.Type.INT); + } else if ( propertyName.contains("files by date") ) { + if (!dateStatisticsMap.containsKey("files by date")) { + dateStatisticsMap.put("files by date", new CdfElement("files by date", "statistics")); + } + dateStatisticsMap.get("files by date").addProperty(propertyName.substring("files by date".length()), property.getValue(), CdfProperty.Type.INT); + } else if ( propertyName.contains("hour of day") ) { + if (!dateStatisticsMap.containsKey("hour of day")) { + dateStatisticsMap.put("hour of day", new CdfElement("hour of day", "statistics")); + } + dateStatisticsMap.get("hour of day").addProperty(propertyName.substring("hour of day".length()), property.getValue(), CdfProperty.Type.INT); + } else if ( propertyName.contains("lines of code") ) { + if (!dateStatisticsMap.containsKey("lines of code")) { + dateStatisticsMap.put("lines of code", new CdfElement("lines of code", "statistics")); + } + dateStatisticsMap.get("lines of code").addProperty(propertyName.substring("lines of code".length()), property.getValue(), CdfProperty.Type.INT); + } else if ( propertyName.contains("month of year") ) { + if (!dateStatisticsMap.containsKey("month of year")) { + dateStatisticsMap.put("month of year", new CdfElement("month of year", "statistics")); + } + dateStatisticsMap.get("month of year").addProperty(propertyName.substring("month of year".length()), property.getValue(), CdfProperty.Type.INT); + } else { + otherProperties.add(property); + } + } + + + + + CdfElement root = new CdfElement("root", "root"); + tree.setRoot(root); + for ( String key : rowElementMap.keySet() ) { + CdfElement row = new CdfElement(key, "row"); + row.addChildElement(rowElementMap.get(key)); + root.addChildElement(row); + } + for ( String key : dateStatisticsMap.keySet()) { + CdfElement stat = new CdfElement(key, "stat"); + stat.addChildElement(dateStatisticsMap.get(key)); + root.addChildElement(stat); + } + for ( CdfProperty property : otherProperties) { + root.addProperty(property.getName(), property.getValue(), property.getType()); + } + + return tree; + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatConverter.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatConverter.java new file mode 100644 index 00000000..07c3c483 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatConverter.java @@ -0,0 +1,36 @@ +package codemetropolis.toolchain.converter.gitstat; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.commons.cdf.CdfTree; +import codemetropolis.toolchain.commons.cdf.converter.CdfConverter; +import codemetropolis.toolchain.commons.exceptions.CodeMetropolisException; + + +public class GitStatConverter extends CdfConverter { + + private static final String GITSTAT_ELEMENT_NAME = "GitStat"; + private static final String GITSTAT_ELEMENT_BASE_TYPE = "statistics"; + + public GitStatConverter(Map params) { + super(params); + } + + @Override + public CdfTree createElements(String source) throws CodeMetropolisException { + List properties = new ArrayList<>(); + properties = PropertyCollector.collect(source); + + // this version only makes one element, which contains all the properties + // with TreeBuilder it can be extended to create nested elements + CdfElement element = new CdfElement(GITSTAT_ELEMENT_NAME, GITSTAT_ELEMENT_BASE_TYPE); + CdfTree tree = CdfTreeBuilder.createTree(element, properties); + + return tree; + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatDatParser.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatDatParser.java new file mode 100644 index 00000000..642c1f68 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatDatParser.java @@ -0,0 +1,81 @@ +package codemetropolis.toolchain.converter.gitstat; + + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; + +public class GitStatDatParser { + //dat files names: + final String[] names = { "commits_by_year", "commits_by_year_month", "day_of_week", "domains", "files_by_date", + "hour_of_day", "lines_of_code", "month_of_year" }; + + /**Load all lines from GitStat dat files into an ArrayList of CdfProperty + * @param folder string representation of the dat files folder + * @return An ArrayList of CdfProperty + */ + public static List getPropertiesFromDatFiles(String folder) { + List properties = new ArrayList(); + + //get a List of string representation from all dat files. The from is for example: commits_by_year_2014 1 + List lines = getLinesFromDatFiles(folder); + + Iterator itr = lines.iterator(); + + while (itr.hasNext()) { + String next = itr.next().toString(); + //cut the line on whitespace and replace _ to whitespace for example: commits_by_year_2014 1 -> term = "commits by year 2014", description = "1" + StringTokenizer st = new StringTokenizer(next); + String term = st.nextToken().trim().replace("_", " "); + String description = st.nextToken(); + + //add a new CdfProperty to properties list + properties.add(new CdfProperty(term, description, CdfProperty.Type.INT)); + } + + System.out.println(properties); + return properties; + } + + + /**Get lines from all rows of dat files plus add filename for example commits_by_year_2014 1 + * @param folder string representation of the folder path + * @return lines a list of string from all rows of dat files + */ + public static List getLinesFromDatFiles(String folder) { + List lines = new ArrayList(); + try { + List files = GitStatFileHelper.searchForFile(folder, ".dat"); + for (String file : files) { + + List newLines = GitStatFileHelper.getLinesFromFile(file); + + for (String line : newLines) { + line = GitStatDatParser.getPropertyPreNameFromFileName(file) + line; + + lines.add(line); + } + + + } + } catch (IOException e) { + e.printStackTrace(); + } + return lines; + } + + /**Get filename without extension and a _ character + * @param fileName string representation of the dat filename + * @return filename without extension and a _ character for example commits_by_year_ + */ + public static String getPropertyPreNameFromFileName(String fileName) { + + return fileName + "_"; + + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatFileHelper.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatFileHelper.java new file mode 100644 index 00000000..33642056 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatFileHelper.java @@ -0,0 +1,58 @@ +package codemetropolis.toolchain.converter.gitstat; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class GitStatFileHelper { + + /**Loading all lines from a file into an ArrayList<> + * @param filepath string representation of the file path + * @return all lines of the file loaded in a list + **/ + public static List getLinesFromFile(String filepath) throws IOException + { + if (filepath == null) { + return null; + } + List lines = Files.readAllLines(Paths.get(filepath), Charset.forName("UTF-8")); + /*for(String line : lines){ + System.out.println(line); + }*/ + return lines; + } + + /**Lists all files in a folder that ends with the given file extension or filename. + * @param folder string representation of the folder path + * @param type file extension or filename with extension e.g.: ".txt" or "tags.html" + * @return Path of the files in the directory with the given extension or name in a List<> + **/ + public static List searchForFile(String folder, String type) + { + if (folder != null && type != null ) { + List selectedFiles = new ArrayList(); + DirectoryStream.Filter filter = new DirectoryStream.Filter() { + public boolean accept(Path file) throws IOException { + return (!Files.isDirectory(file) && file.getFileName().toString().toLowerCase().endsWith(type)); + } + }; + + try (DirectoryStream stream = Files.newDirectoryStream(Paths.get(folder), filter)) { + for (Path entry : stream) { + selectedFiles.add(entry.toString()); + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + return selectedFiles; + } else { + return new ArrayList(); + } + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatHTMLParser.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatHTMLParser.java new file mode 100644 index 00000000..e20e2b51 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/GitStatHTMLParser.java @@ -0,0 +1,111 @@ +package codemetropolis.toolchain.converter.gitstat; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; + +public class GitStatHTMLParser { + + public static List getPropertiesFromHTMLFiles(String folder){ + List properties = new ArrayList(); + + List lines = getLinesFromHTMLFiles(folder); + + Iterator itr = lines.iterator(); + + while (itr.hasNext()) { + String next = itr.next().toString().trim().replaceAll("\t", ""); + if (next.startsWith("
")) { + List newProperties = descriptionListToProperty(itr); + properties.addAll(newProperties); + } + else if (next.startsWith("")) { + List newProperties = tableToProperty(itr, "Extensions"); + properties.addAll(newProperties); + } + } + System.out.println(properties); + return properties; + } + + public static List getLinesFromHTMLFiles(String folder){ + List lines = new ArrayList(); + try { + List files = GitStatFileHelper.searchForFile(folder, ".html"); + for (String file : files) { + System.out.println(file); + List newLines = GitStatFileHelper.getLinesFromFile(file); + lines.addAll(newLines); + } + } catch (IOException e) { + e.printStackTrace(); + } + return lines; + } + + private static List descriptionListToProperty(Iterator itr){ + List newProperties = new ArrayList(); + String term = itr.next().toString().trim().replaceAll("\t", ""); + do { + term = term.replaceAll("
", "").replaceAll("
", ""); + String description = itr.next().toString().trim().replaceAll("\t", "").replaceAll("
", "").replaceAll("
", ""); + if (isNumber(description)) { + newProperties.add(new CdfProperty(term, description, CdfProperty.Type.INT)); + } + else { + newProperties.add(new CdfProperty(term, description, CdfProperty.Type.STRING)); + } + //System.out.println(newProperties); + term = itr.next().toString().trim(); + } + while (!term.startsWith("")); + + return newProperties; + } + + private static List tableToProperty(Iterator itr, String tableName){ + int rowCount = 1; + List newProperties = new ArrayList(); + List headers = new ArrayList(); + + itr.next(); + String line = itr.next().toString().trim().replaceAll("\t", ""); + + while (!line.startsWith("")) { + line = line.replaceAll("
", ""); + headers.add(line); + line = itr.next().toString().trim().replaceAll("\t", ""); + } + + line = itr.next().toString().trim().replaceAll("\t", ""); + + while (!line.startsWith("
", "").replaceAll("
")) { + for (int i=0; i< headers.size(); i++) { + line = itr.next().toString().trim().replaceAll("\t", "").replaceAll("", "").replaceAll("", ""); + if (isNumber(line)) { + newProperties.add(new CdfProperty(tableName + "_Table_Row" + rowCount + "_" + headers.get(i), line, CdfProperty.Type.INT)); + } + else { + newProperties.add(new CdfProperty(tableName + "_Table_Row" + rowCount + "_" + headers.get(i), line, CdfProperty.Type.STRING)); + } + } + rowCount++; + itr.next(); + line = itr.next().toString().trim().replaceAll("\t", ""); + } + return newProperties; + } + + public static boolean isNumber(String value) { + try { + Integer.parseInt(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/PropertyCollector.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/PropertyCollector.java new file mode 100644 index 00000000..cc4b7540 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/gitstat/PropertyCollector.java @@ -0,0 +1,22 @@ +package codemetropolis.toolchain.converter.gitstat; + +import java.util.ArrayList; +import java.util.List; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; + +public class PropertyCollector { + + public static List collect(String source) { + List collectedProperties = new ArrayList<>(); + + if ( source != null ) { + collectedProperties.addAll(GitStatHTMLParser.getPropertiesFromHTMLFiles(source)); + collectedProperties.addAll(GitStatDatParser.getPropertiesFromDatFiles(source)); + } + + return collectedProperties; + + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/pmd/PmdConverter.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/pmd/PmdConverter.java new file mode 100644 index 00000000..13900163 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/pmd/PmdConverter.java @@ -0,0 +1,137 @@ +package codemetropolis.toolchain.converter.pmd; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.commons.cdf.CdfTree; +import codemetropolis.toolchain.commons.cdf.converter.CdfConverter; +import codemetropolis.toolchain.commons.exceptions.CodeMetropolisException; +import codemetropolis.toolchain.commons.cdf.CdfProperty; + +public class PmdConverter extends CdfConverter { + + int vCounter = 0; + + public PmdConverter(Map params) { + super(params); + } + + @Override + public CdfTree createElements(String source) throws CodeMetropolisException { + + vCounter = 0; + Document doc = loadXml(source); + CdfElement root = createElementsRecursively(doc); + CdfTree tree = new CdfTree(); + tree.setRoot(root); + return tree; + } + + public CdfElement createElementsRecursively(Node root) { + CdfElement element = null; + element = cdfConvert(root); + if (element != null) { + addProperties(element, root); + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + CdfElement e = createElementsRecursively(children.item(i)); + if (e != null) { + element.addChildElement(e); + } + } + } + return element; + + } + + public void addProperties(CdfElement elem, Node n) { + if (n.hasAttributes()) { + NamedNodeMap map = n.getAttributes(); + for (int i = 0; i < map.getLength(); i++) { + + elem.addProperty(map.item(i).getNodeName(), map.item(i).getNodeValue(), + convertType(map.item(i).getNodeValue())); + } + } + } + + public CdfElement cdfConvert(Node n) { + CdfElement elem = null; + switch (n.getNodeName()) { + case "violation": + elem = new CdfElement(("violation" + vCounter), "violation"); + vCounter++; + break; + case "file": + elem = new CdfElement(n.getAttributes().getNamedItem("name").getNodeValue(), "file"); + break; + case "#document": + case "pmd": + elem = new CdfElement(n.getNodeName(), "other"); + break; + default: + + break; + } + + return elem; + + } + + public CdfProperty.Type convertType(String str) { + + if (isNumeric(str)) + return CdfProperty.Type.INT; + else + return CdfProperty.Type.STRING; + + } + + public boolean isNumeric(String str) { + if (str.chars().allMatch(Character::isDigit)) + return true; + else + return false; + + } + + public Document parseXml(String source, DocumentBuilder dBuilder) { + File xmlFile = new File(source); + Document doc = null; + try { + doc = dBuilder.parse(xmlFile); + } catch (SAXException e) { + System.out.println("Parsing xml input has failed"); + } catch (IOException e) { + + System.out.println("Reading xml input has failed"); + } + return doc; + } + + public Document loadXml(String source) { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + ; + DocumentBuilder dBuilder = null; + + try { + dBuilder = dbFactory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + System.out.println("Parse Configuration has failed"); + } + Document doc = parseXml(source, dBuilder); + return doc; + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/relations/RelationFileParser.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/relations/RelationFileParser.java new file mode 100644 index 00000000..e693b209 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/relations/RelationFileParser.java @@ -0,0 +1,224 @@ +package codemetropolis.toolchain.converter.relations; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +public class RelationFileParser { + + // Map to store the relations between classes, first argument is the key, the ID of the class + // second argument is the child classes of the first argument (it can be null that means they have no child) + private Map> relationsMap = new HashMap>(); + + // Map to store the attribute types (classes) of the classes + // KEY: ID of the class, VALUE: list of attribute type (class) IDs + private Map> attributesMap = new HashMap>(); + + private String relationFile = null; + + private NodeList classList; + private NodeList typeList; + private NodeList typeFormerTypeList; + + public RelationFileParser(String relationFile) { + this.relationFile = relationFile; + } + + public void parseRelationFile() throws ParserConfigurationException, SAXException, IOException { + + File inputFile = new File(relationFile); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(inputFile); + doc.getDocumentElement().normalize(); + + classList = doc.getElementsByTagName("logical:Class"); + typeList = doc.getElementsByTagName("type:Type"); + typeFormerTypeList = doc.getElementsByTagName("type:TypeFormerType"); + + for (int iClass = 0; iClass < classList.getLength(); iClass++) { + + Node nClass = classList.item(iClass); + String idClass = nClass.getAttributes().getNamedItem("id").getNodeValue(); + + NodeList classChildren = nClass.getChildNodes(); + for (int iClassChild = 0; iClassChild < classChildren.getLength(); iClassChild++) { + Node nClassChild = classChildren.item(iClassChild); + + // if the child is a subclass + if ("Class_IsSubclass".equals(nClassChild.getNodeName())) { + getSubclassRelation(nClassChild, idClass); + } + + // if the child is an attribute in class + if ("logical:Attribute".equals(nClassChild.getNodeName())) { + // get children + NodeList attrChildren = nClassChild.getChildNodes(); + getAttributeRelations(nClass, attrChildren); + + } + } + } + } + + private void getSubclassRelation(Node nClassChild, String idClass) { + String refType = nClassChild.getAttributes().getNamedItem("ref").getNodeValue(); + if (refType == null) { + return; + } + String refTypeFormerType = getTypeFormerTypeRefFromTypes(refType); + if (refTypeFormerType == null ) { + return; + } + String refParent = getClassRefFromTypeFormerTypes(refTypeFormerType); + if (refParent == null) { + return; + } + + refParent = refParent.replaceAll("id", "L"); + idClass = idClass.replaceAll("id", "L"); + + ArrayList children; + children = relationsMap.get(refParent); + + if (children != null) { + children.add(idClass); + } else { + children = new ArrayList(); + children.add(idClass); + } + relationsMap.put(refParent, children); + } + + + private void getAttributeRelations(Node nClass, NodeList attrChildren) { + + for (int iAttrChild = 0; iAttrChild < attrChildren.getLength(); ++iAttrChild) { + + Node nAttrChild = attrChildren.item(iAttrChild); + if ("Attribute_HasType".equals(nAttrChild.getNodeName())) { + + String refType = nAttrChild.getAttributes().getNamedItem("ref").getNodeValue(); + if (refType == null) { + return; + } + String refTypeFormerType = getTypeFormerTypeRefFromTypes(refType); + if (refTypeFormerType == null ) { + return; + } + String refAttrClass = getClassRefFromTypeFormerTypes(refTypeFormerType); + if (refAttrClass == null) { + return; + } + + + // search for classes with obtained id (may not need, but builtins are excluded this way for sure) + for (int iAttrClass = 0; iAttrClass < classList.getLength(); ++iAttrClass) { + Node nAttrClass = classList.item(iAttrClass); + String idAttrClass = nAttrClass.getAttributes().getNamedItem("id").getNodeValue(); + if (refAttrClass.equals(idAttrClass)) { + + // add attribute to attributesMap (init list if it does not exist) + String keyClass = nClass.getAttributes().getNamedItem("id").getNodeValue().replaceAll("id", "L"); + String keyAttrClass = idAttrClass.replaceAll("id", "L"); + ArrayList attributes = attributesMap.get(keyClass); + if (attributes == null) { + attributes = new ArrayList(); + attributesMap.put(keyClass, attributes); + } + attributes.add(keyAttrClass); + break; + } + } + } + } + } + + private String getTypeFormerTypeRefFromTypes(String ref) { + + // search for type with obtained id + for (int iType = 0; iType < typeList.getLength(); ++iType) { + Node nType = typeList.item(iType); + String idType = nType.getAttributes().getNamedItem("id").getNodeValue(); + if (ref.equals(idType)) { + + // get typeFormerType ref from type + NodeList typeChildren = nType.getChildNodes(); + for (int iTypeChildren = 0; iTypeChildren < typeChildren.getLength(); ++iTypeChildren) { + Node typeChild = typeChildren.item(iTypeChildren); + if ("Type_HasTypeFormer".equals(typeChild.getNodeName())) { + String refTypeFormerType = typeChild.getAttributes().getNamedItem("ref").getNodeValue(); + return refTypeFormerType; + } + } + } + } + // should not happen + return null; + + } + + private String getClassRefFromTypeFormerTypes(String ref) { + + // search for typeFormerType with obtained id + for (int iTypeFormerType = 0; iTypeFormerType < typeFormerTypeList.getLength(); ++iTypeFormerType) { + Node typeFormerType = typeFormerTypeList.item(iTypeFormerType); + String idTypeFormerType = typeFormerType.getAttributes().getNamedItem("id").getNodeValue(); + if (ref.equals(idTypeFormerType)) { + + // get class ref from typeFormerType + NodeList typeFormerTypeChildren = typeFormerType.getChildNodes(); + for (int iTypeFormerTypeChild = 0; iTypeFormerTypeChild < typeFormerTypeChildren.getLength(); ++iTypeFormerTypeChild) { + Node typeFormerTypeChild = typeFormerTypeChildren.item(iTypeFormerTypeChild); + if ("TypeFormerType_RefersTo".equals(typeFormerTypeChild.getNodeName())) { + String refClass = typeFormerTypeChild.getAttributes().getNamedItem("ref").getNodeValue(); + return refClass; + } + } + } + } + // should not happen + return null; + } + + + public Map> getRelationsMap() { + return relationsMap; + } + + public Map> getAttributesMap() { + return attributesMap; + } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + + for (String key : relationsMap.keySet()) { + s.append("Class: " + key + " -> " + "SubClasses: " + relationsMap.get(key) + " | "); + } + + for (String key : attributesMap.keySet()) { + s.append("Class: " + key + " -> " + "Attributes: " + attributesMap.get(key) + " | "); + } + + return s.toString(); + } + + public String getRelationFile() { + return relationFile; + } + + public void setRelationFile(String relationFile) { + this.relationFile = relationFile; + } +} diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/relations/Relations.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/relations/Relations.java new file mode 100644 index 00000000..0a44c346 --- /dev/null +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/relations/Relations.java @@ -0,0 +1,231 @@ +package codemetropolis.toolchain.converter.relations; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; +import java.util.*; + +public class Relations { + + // Map to store the relations between classes, first argument is the key, the ID of the class + // second argument is the child classes of the first argument (it can be null that means they have no child) + private Map> relationsMap = new HashMap>(); + + // Map to store the attribute types (classes) of the classes + // KEY: ID of the class, VALUE: list of attribute type (class) IDs + private Map> attributesMap = new HashMap>(); + + private String relationFile = null; + + public Relations(String relationFile) { + this.relationFile = relationFile; + } + + public void parseRelationFile() { + + try { + + System.out.println(relationFile); + + File inputFile = new File(relationFile); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(inputFile); + doc.getDocumentElement().normalize(); + System.out.println("Root element :" + doc.getDocumentElement().getNodeName()); + + NodeList classList = doc.getElementsByTagName("logical:Class"); + NodeList typeList = doc.getElementsByTagName("type:Type"); + NodeList typeFormerTypeList = doc.getElementsByTagName("type:TypeFormerType"); + + String refIdToRelation = null; + String refIdToRelation2 = null; + String parent = null; + String currentClass = null; + + // TODO: too complex + for (int iClass = 0; iClass < classList.getLength(); iClass++) { + Node nNode = classList.item(iClass); + System.out.println("\nCurrent Element :" + nNode.getNodeName()); + Element currentClassNode = (Element) nNode; + currentClass = currentClassNode.getAttribute("id"); + + for (int iClassChild = 0; iClassChild < nNode.getChildNodes().getLength(); iClassChild++) { + Node n = nNode.getChildNodes().item(iClassChild); + + if ("Class_IsSubclass".equals(n.getNodeName())) { + Element classListElement = (Element) n; + //System.out.println("Class_IsSubclass REF = " + classListElement.getAttribute("ref")); + refIdToRelation = ((Element) n).getAttribute("ref"); + + for (int iType = 0; iType < typeList.getLength(); iType++) { + Node nNodeType = typeList.item(iType); + ((Element) nNodeType).getAttribute("id"); + + // If the type was found search for "Type_HasTypeFormer" ref + if (refIdToRelation.equals(((Element) nNodeType).getAttribute("id"))) { + + for (int iTypeChild = 0; iTypeChild < nNodeType.getChildNodes().getLength(); iTypeChild++) { + Node n2 = nNodeType.getChildNodes().item(iTypeChild); + + if ("Type_HasTypeFormer".equals(n2.getNodeName())) { + Element hasTypeFormerElement = (Element) n2; + refIdToRelation2 = hasTypeFormerElement.getAttribute("ref"); + //System.out.println("GOOOD: " + refIdToRelation2); + + // // If the Type_HasTypeFormer was found search for "TypeFormerType_RefersTo" ref + for (int iTypeFormerType = 0; iTypeFormerType < typeFormerTypeList.getLength(); iTypeFormerType++) { + Node nNodeTypeFormerType = typeFormerTypeList.item(iTypeFormerType); + ((Element) nNodeTypeFormerType).getAttribute("id"); //? + + // If the type was found search for "Type_HasTypeFormer" ref + if (refIdToRelation2.equals(((Element) nNodeTypeFormerType).getAttribute("id"))) { + + for (int iTypeFormerTypeChild = 0; iTypeFormerTypeChild < nNodeTypeFormerType.getChildNodes().getLength(); iTypeFormerTypeChild++) { + Node n3 = nNodeTypeFormerType.getChildNodes().item(iTypeFormerTypeChild); + + if ("TypeFormerType_RefersTo".equals(n3.getNodeName())) { + Element hasTypeFormerTypeRefersToElement = (Element) n3; + parent = hasTypeFormerTypeRefersToElement.getAttribute("ref"); + //System.out.println("PARENT: " + parent); + + parent = parent.replaceAll("id", "L"); + currentClass = currentClass.replaceAll("id", "L"); + + ArrayList childs; + childs = relationsMap.get(parent); + + if (childs != null) { + childs.add(currentClass); + } else { + childs = new ArrayList(); + childs.add(currentClass); + } + relationsMap.put(parent, childs); + } + } + } + } + } + } + } + } + } + + // if the child is an attribute in class + if ("logical:Attribute".equals(n.getNodeName())) { + System.out.println("attrnode " + n.getNodeName()); + + // get the type of the attribute + NodeList attrChildren = n.getChildNodes(); + for (int iAttrChild = 0; iAttrChild < attrChildren.getLength(); ++iAttrChild) { + Node attrChild = attrChildren.item(iAttrChild); + if ("Attribute_HasType".equals(attrChild.getNodeName())) { + System.out.println("hastype child found"); + String typeRef = attrChild.getAttributes().getNamedItem("ref").getNodeValue(); + + // search for type with obtained id + for (int iType = 0; iType < typeList.getLength(); ++iType) { + Node type = typeList.item(iType); + String typeId = type.getAttributes().getNamedItem("id").getNodeValue(); + if (typeRef.equals(typeId)) { + System.out.println("typeId found " + typeId); + + // get typeFormerType ref from type + NodeList typeChildren = type.getChildNodes(); + for (int iTypeChildren = 0; iTypeChildren < typeChildren.getLength(); ++iTypeChildren) { + Node typeChild = typeChildren.item(iTypeChildren); + if ("Type_HasTypeFormer".equals(typeChild.getNodeName())) { + System.out.println("hastypeformer child found"); + String typeFormerTypeRef = typeChild.getAttributes().getNamedItem("ref").getNodeValue(); + + // search for typeFormerType with obtained id + for (int iTypeFormerType = 0; iTypeFormerType < typeFormerTypeList.getLength(); ++iTypeFormerType) { + Node typeFormerType = typeFormerTypeList.item(iTypeFormerType); + String typeFormerTypeId = typeFormerType.getAttributes().getNamedItem("id").getNodeValue(); + if (typeFormerTypeRef.equals(typeFormerTypeId)) { + System.out.println("typeFormerTypeId found " + typeFormerTypeId); + + + // get class ref from typeFormerType + NodeList typeFormerTypeChildren = typeFormerType.getChildNodes(); + for (int iTypeFormerTypeChild = 0; iTypeFormerTypeChild < typeFormerTypeChildren.getLength(); ++iTypeFormerTypeChild) { + Node typeFormerTypeChild = typeFormerTypeChildren.item(iTypeFormerTypeChild); + if ("TypeFormerType_RefersTo".equals(typeFormerTypeChild.getNodeName())) { + System.out.println("TypeFormerType_RefersTo child found"); + String classRef = typeFormerTypeChild.getAttributes().getNamedItem("ref").getNodeValue(); + + // search for classes with obtained id (may not need, but builtins are excluded this way for sure) + for (int jClass = 0; jClass < classList.getLength(); ++jClass) { + Node klass = classList.item(jClass); + String classId = klass.getAttributes().getNamedItem("id").getNodeValue(); + if (classRef.equals(classId)) { + System.out.println("classId found " + classId); + + // add attribute to attributesMap (init list if it does not exist) + String classKey = nNode.getAttributes().getNamedItem("id").getNodeValue().replaceAll("id", "L"); + String attrClassKey = classId.replaceAll("id", "L"); + ArrayList attributes = attributesMap.get(classKey); + if (attributes == null) { + attributes = new ArrayList(); + attributesMap.put(classKey, attributes); + } + attributes.add(attrClassKey); + System.out.println("attribute added: " + classKey + ":" + attrClassKey); + break; + } + } + break; + } + } + break; + } + } + break; + } + } + break; + } + } + break; + } + } + } + } + } + } catch (Exception e) { + // TODO: throw a normal error message + e.printStackTrace(); + } + } + + public Map> getRelationsMap() { + return relationsMap; + } + + public Map> getAttributesMap() { + return attributesMap; + } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + + // TODO complete with attributes + + for (String key : relationsMap.keySet()) { + s.append("Class: " + key + " -> " + "SubClasses: " + relationsMap.get(key) + " | "); + } + + for (String key : attributesMap.keySet()) { + s.append("Class: " + key + " -> " + "Attributes: " + attributesMap.get(key) + " | "); + } + + return s.toString(); + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/sourcemeter/GraphConverter.java b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/sourcemeter/GraphConverter.java index 3adf340d..a2930c71 100644 --- a/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/sourcemeter/GraphConverter.java +++ b/sources/toolchain/converter/src/main/java/codemetropolis/toolchain/converter/sourcemeter/GraphConverter.java @@ -3,11 +3,11 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; - import codemetropolis.toolchain.commons.cdf.CdfElement; import codemetropolis.toolchain.commons.cdf.CdfTree; import codemetropolis.toolchain.commons.cdf.converter.CdfConverter; import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.relations.Relations; import graphlib.Attribute; import graphlib.Attribute.AttributeIterator; import graphlib.AttributeFloat; @@ -27,8 +27,23 @@ public GraphConverter(Map params) { private static final String ROOT_NODE_ID = "L100"; + private boolean isRelationsNeeded = false; + private Relations relations = null; + @Override public CdfTree createElements(String graphPath) { + if (getParameter("relationFile") != null) { + isRelationsNeeded = true; + relations = new Relations(getParameter("relationFile")); + + try { + relations.parseRelationFile(); + } catch (Exception e) { + System.err.println("Error during parse relation file: " + getParameter("relationFile") + " (File may not exist)"); + } + + } + Graph graph = new Graph(); graph.loadBinary(graphPath); Node root = graph.findNode(ROOT_NODE_ID); @@ -40,6 +55,25 @@ private CdfElement createElementsRecursively(Node root) { String name = ((AttributeString)root.findAttributeByName("Name").next()).getValue(); String type = root.getType().getType(); CdfElement element = new CdfElement(name, type); + if ("Class".equals(type) && isRelationsNeeded) { + // if the element is a class, check for subclasses from relationFile + + if (relations.getRelationsMap().get(root.getUID()) != null) { + String classId = relations.getRelationsMap().get(root.getUID()).toString(); + element.addProperty("ChildClasses", classId, CdfProperty.Type.STRING); + } else { + element.addProperty("ChildClasses", "", CdfProperty.Type.STRING); + } + + // check for attributes + if (relations.getAttributesMap().get(root.getUID()) != null) { + String classId = relations.getAttributesMap().get(root.getUID()).toString(); + element.addProperty("AttributeClasses", classId, CdfProperty.Type.STRING); + + } else { + element.addProperty("AttributeClasses", "", CdfProperty.Type.STRING); + } + } element.setSourceId(root.getUID()); addProperties(root, element); for(Node child : getChildNodes(root)) { diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/commons/cmxml/BuildableTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/commons/cmxml/BuildableTest.java new file mode 100644 index 00000000..f8a33725 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/commons/cmxml/BuildableTest.java @@ -0,0 +1,26 @@ +package codemetropolis.toolchain.commons.cmxml; + +import codemetropolis.toolchain.commons.cmxml.Buildable.Type; +import junit.framework.TestCase; + +public class BuildableTest extends TestCase { + + Buildable b1, b2, b3; + + public void setup() { + b1 = null; + b2 = null; + b3 = null; + } + + public void testIsOverlapping() { + b1 = new Buildable("test1", "testBuilding1", Type.FLOOR, new Point(0, 0, 0), new Point(2, 2, 2)); + b2 = new Buildable("test2", "testBuilding2", Type.FLOOR, new Point(1, 1, 1), new Point(2, 2, 2)); + b3 = new Buildable("test3", "testBuilding3", Type.FLOOR, new Point(-1, -1, -1), new Point(2, 2, 2)); + + assertTrue(b1.isOverlapping(b2)); + assertTrue(b3.isOverlapping(b1)); + assertFalse(b2.isOverlapping(b3)); + } + +} diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/commons/cmxml/PointTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/commons/cmxml/PointTest.java new file mode 100644 index 00000000..c98c8a8a --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/commons/cmxml/PointTest.java @@ -0,0 +1,23 @@ +package codemetropolis.toolchain.commons.cmxml; + +import junit.framework.TestCase; + +public class PointTest extends TestCase { + + Point testObj; + + public void setup() { + testObj = null; + } + + public void testTranslate() { + testObj = new Point(0, 0, 0); + + Point newPoint = testObj.translate(new Point(1, 2, 3)); + + assertEquals(1, newPoint.getX()); + assertEquals(2, newPoint.getY()); + assertEquals(3, newPoint.getZ()); + } + +} diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/commons/util/TimeTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/commons/util/TimeTest.java new file mode 100644 index 00000000..1ab330aa --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/commons/util/TimeTest.java @@ -0,0 +1,58 @@ +package codemetropolis.toolchain.commons.util; + +import junit.framework.TestCase; + +public class TimeTest extends TestCase { + + Time testObj; + + public void setup() { + testObj = null; + } + + public void testGetHours() { + testObj = new Time(0); + assertEquals(0, testObj.getHours()); + + testObj = new Time(3599999); // 0 hrs 59 mins 59 seconds, 999 milliseconds + assertEquals(0, testObj.getHours()); + + testObj = new Time(86400001); // 24 hrs 1 milliseconds + assertEquals(24, testObj.getHours()); + } + + public void testGetMinutes() { + testObj = new Time(0); + assertEquals(0, testObj.getMinutes()); + + testObj = new Time(6999); + assertEquals(0, testObj.getMinutes()); + + testObj = new Time(59999); + assertEquals(0, testObj.getMinutes()); + + testObj = new Time(60000); + assertEquals(1, testObj.getMinutes()); + + testObj = new Time(3600000); + assertEquals(0, testObj.getMinutes()); + + testObj = new Time(3730000); + assertEquals(2, testObj.getMinutes()); + } + + public void testGetSeconds() { + testObj = new Time(0); + assertEquals(0, testObj.getSeconds()); + + testObj = new Time(3999); + assertEquals(3, testObj.getSeconds()); + + testObj = new Time(60000); + assertEquals(0, testObj.getSeconds()); + + testObj = new Time(74500); + assertEquals(14, testObj.getSeconds()); + } + +} diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/ConverterExecutorArgsTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/ConverterExecutorArgsTest.java new file mode 100644 index 00000000..561d0a7f --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/ConverterExecutorArgsTest.java @@ -0,0 +1,30 @@ +package codemetropolis.toolchain.converter; + +import java.util.HashMap; + +import codemetropolis.toolchain.converter.control.ConverterType; +import junit.framework.TestCase; + +public class ConverterExecutorArgsTest extends TestCase { + ConverterExecutorArgs testObj; + + public void setup () { + testObj = null; + } + + public void testConverterExecutorArgsConstructorNoParams() { + testObj = new ConverterExecutorArgs(ConverterType.SOURCEMETER, "testSource", "testOutput"); + assertEquals("testOutput", testObj.getOutputFile()); + assertEquals("testSource", testObj.getSource()); + assertEquals(ConverterType.SOURCEMETER, testObj.getType()); + } + + public void testConverterExecutorArgsConstructor() { + testObj = new ConverterExecutorArgs(ConverterType.SONARQUBE, "testSource", "testOutput", new HashMap()); + assertEquals("testOutput", testObj.getOutputFile()); + assertEquals("testSource", testObj.getSource()); + assertEquals(ConverterType.SONARQUBE, testObj.getType()); + assertNotNull(testObj.getParams()); + assertTrue(testObj.getParams().isEmpty()); + } +} diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/control/ConverterLoaderTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/control/ConverterLoaderTest.java new file mode 100644 index 00000000..768a950a --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/control/ConverterLoaderTest.java @@ -0,0 +1,27 @@ +package codemetropolis.toolchain.converter.control; + +import java.util.HashMap; +import codemetropolis.toolchain.commons.cdf.converter.CdfConverter; +import codemetropolis.toolchain.converter.sonarqube.SonarQubeConverter; +import codemetropolis.toolchain.converter.sourcemeter.GraphConverter; +import junit.framework.TestCase; + +public class ConverterLoaderTest extends TestCase { + + CdfConverter result; + + + public void setup() { + result = null; + } + + public void testLoadSourceMeter() { + result = ConverterLoader.load(ConverterType.SOURCEMETER, new HashMap()); + assert(result instanceof GraphConverter); + } + + public void testLoadSonarQube() { + result = ConverterLoader.load(ConverterType.SONARQUBE, new HashMap()); + assert(result instanceof SonarQubeConverter); + } +} diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/BranchTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/BranchTest.java new file mode 100644 index 00000000..d0601d78 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/BranchTest.java @@ -0,0 +1,36 @@ +package codemetropolis.toolchain.converter.gitlab; + +import static org.junit.Assert.*; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import org.junit.BeforeClass; +import org.junit.Test; + +import codemetropolis.toolchain.converter.gitlab.model.Branch; + +import java.util.ArrayList; +import java.util.List; + +public class BranchTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @Test + public void testCreateProperties() { + Branch b = new Branch(); + List list = new ArrayList<>(); + + b.setIsMerged(0); + b.setDevelopersCanPush(1); + b.addProperties(list); + assertEquals(2, list.size()); + } + + @Test + public void testConvertBooleanToInteger() { + assertEquals(0, Branch.convertBooleanToInteger(false)); + assertEquals(1, Branch.convertBooleanToInteger(true)); + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/CommitTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/CommitTest.java new file mode 100644 index 00000000..ae03a80a --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/CommitTest.java @@ -0,0 +1,82 @@ +package codemetropolis.toolchain.converter.gitlab; +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.model.Commit; +import org.gitlab4j.api.GitLabApi; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.List; + + +public class CommitTest { + + private Commit commit; + + private int COMMIT_ADDITION=10; + private int COMMIT_DELETIONS=15; + private int COMMIT_TOTAL=20; + //private int projectID=10; + + private String COMMIT_MESSAGE="Commit branch"; + private String COMMIT_STATUS="success"; + private String ID="aAAAa"; + + @Before + public void setup() { + commit=new Commit(); + GitLabElement.setGitLabApi(new GitLabApi("", "")); + GitLabElement.setProjectID(10); + commit.setID(ID); + commit.setAddition(COMMIT_ADDITION); + commit.setDeletions(COMMIT_DELETIONS); + commit.setStatus(COMMIT_STATUS); + commit.setTotal(COMMIT_TOTAL); + commit.setMessage(COMMIT_MESSAGE); + commit.makeProperties(); + } + + @Test + public void testIfPropertiesConsistsElements() { + + List properties=commit.createProperties(); + Assert.assertTrue(properties.stream().anyMatch(item->(COMMIT_MESSAGE.equals(item.getValue())) + && "message".equals(item.getName()) + && CdfProperty.Type.STRING.equals(item.getType()))); + + } + + @Test + public void testCommitMessageLength() { + + Commit commit=new Commit(); + commit.setID(ID); + commit.setMessage(COMMIT_MESSAGE); + List properties= commit.createProperties(); + Assert.assertTrue(properties.stream().anyMatch(item->("13".equals(item.getValue())) + && "messageLength".equals(item.getName()) && + CdfProperty.Type.INT.equals(item.getType()))); + } + + + + @Test + public void testArraySize() { + List properties=commit.createProperties(); + Assert.assertEquals(7, properties.size()); + } + + @Test + public void testChildren() { + List children= commit.createChildren(); + Assert.assertEquals(0, children.size()); + } + + @Test + public void testIfCommitIDIsNull() { + commit.setID(null); + Assert.assertEquals(true, commit.createProperties().isEmpty()); + + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabClientTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabClientTest.java new file mode 100644 index 00000000..3e73f3a5 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabClientTest.java @@ -0,0 +1,19 @@ +package codemetropolis.toolchain.converter.gitlab; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class GitLabClientTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @Test(expected = GitLabConnectException.class) + public void testAuthentication() throws GitLabConnectException + { + GitLabClient glc = new GitLabClient("mock", "mock", "mock"); + glc.authentication(); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabConverterTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabConverterTest.java new file mode 100644 index 00000000..9c484a33 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabConverterTest.java @@ -0,0 +1,33 @@ +package codemetropolis.toolchain.converter.gitlab; +import static org.junit.Assert.*; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class GitLabConverterTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @Test + public void testGetFullUrl() { + GitLabConverter glc = new GitLabConverter(); + + final String url = "myHostUrl/myGroup/myProject"; + glc.setGroupName("myGroup"); + glc.setHostUrl("myHostUrl"); + glc.setProjectName("myProject"); + + assertEquals(true, glc.createFullUrl().equals(url)); + } + + @Test(expected = java.lang.NullPointerException.class) + public void testAuthentication() throws GitLabConnectException { + GitLabConverter glc = new GitLabConverter(); + glc.setProjectName("simple_project"); + glc.setGroupName("simple_group"); + glc.authentication(); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabElementTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabElementTest.java new file mode 100644 index 00000000..2b50fb77 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabElementTest.java @@ -0,0 +1,63 @@ +package codemetropolis.toolchain.converter.gitlab; +import codemetropolis.toolchain.commons.cdf.CdfProperty; + +import codemetropolis.toolchain.converter.gitlab.model.Issue; +import codemetropolis.toolchain.converter.gitlab.model.Milestone; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +public class GitLabElementTest { + + private static GitLabElement element; + + private String ID="12"; + private String MILESTONE_ID="11"; + + private Issue issue; + private Milestone milestone; + + @BeforeClass + public static void setUp() { + element = new GitLabElement() { + @Override + public List createProperties() { + return new ArrayList<>(); + } + + @Override + public List createChildren() { + return new ArrayList<>(); + } + }; + } + + @Before + public void afterSetUp() { + issue=new Issue(); + issue.setID(ID); + issue.setType(Type.ISSUE); + milestone=new Milestone(); + milestone.setID(MILESTONE_ID); + } + + @Test + public void testIfConsistsGitLabResource() { + GitLabResource.addElement(issue); + element.setType(Type.ISSUE); + element.setID(ID); + + try { + Assert.assertEquals(element.getElement(), issue.getElement()); + } catch (GitLabException e) { + e.printStackTrace(); + } + + GitLabResource.clearMainStorage(); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabResourceTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabResourceTest.java new file mode 100644 index 00000000..d4a30589 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/GitLabResourceTest.java @@ -0,0 +1,115 @@ +package codemetropolis.toolchain.converter.gitlab; + +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.converter.gitlab.model.Commit; +import org.gitlab4j.api.GitLabApi; +import org.junit.*; +import org.junit.rules.ExpectedException; +import codemetropolis.toolchain.converter.gitlab.model.Branch; +import codemetropolis.toolchain.converter.gitlab.model.Project; + +import static org.junit.Assert.assertEquals; + +public class GitLabResourceTest { + + private static Commit commit; + + private String COMMIT_MESSAGE="Commit branch"; + private String COMMIT_STATUS="success"; + private String ID = "aAAAa"; + + private int COMMIT_ADDITION=10; + private int COMMIT_DELETIONS=15; + private int COMMIT_TOTAL=20; + //private int projectID=10; + + @BeforeClass + public static void setUp() { + commit=new Commit(); + GitLabElement.setGitLabApi(new GitLabApi("", "")); + GitLabElement.setProjectID(10); + } + + @Before + public void afterSetUp() { + GitLabResource.clearMainStorage(); + commit.setID(ID); + commit.setAddition(COMMIT_ADDITION); + commit.setDeletions(COMMIT_DELETIONS); + commit.setStatus(COMMIT_STATUS); + commit.setTotal(COMMIT_TOTAL); + commit.setMessage(COMMIT_MESSAGE); + } + + @Test + public void testConsistsOf() { + GitLabElement branch = new Branch(); + branch.setID("myBelovedBranch"); + branch.setType(Type.BRANCH); + + assertEquals(false, GitLabResource.consistsOf(Type.BRANCH, "myBelovedBranch")); + GitLabResource.addElement(branch); + + assertEquals(false, GitLabResource.consistsOf(Type.COMMIT, "non-existing-commit")); + assertEquals(true, GitLabResource.consistsOf(Type.BRANCH, "myBelovedBranch")); + } + + @Test + public void testAddElement() { + GitLabElement project = new Project(); + project.setID("root"); + project.setType(Type.PROJECT); + + GitLabElement project2 = new Project(); + project2.setID("root"); + project2.setType(Type.PROJECT); + + + assertEquals(true, GitLabResource.addElement(project)); + assertEquals(false, GitLabResource.addElement(project2)); + } + + @Test + public void testAddParentID() { + GitLabElement commit = new Commit(); + commit.setID("c1"); + commit.addParentID("parent_c1"); + assertEquals(true, commit.getParentIds().contains("parent_c1")); + } + + @Test + public void testIfReturnsTheSameValue() { + CdfElement element=new CdfElement(); + CdfElement element2=new CdfElement(); + + try { + element = GitLabResource.getElement(Type.COMMIT, ID, "aaa"); + element2 = GitLabResource.getElement(Type.COMMIT, ID, "aaa"); + } catch (GitLabException e) { + e.printStackTrace(); + } + + Assert.assertEquals(element2, element); + + GitLabResource.clearMainStorage(); + } + + @Rule + public ExpectedException thrown=ExpectedException.none(); + + @Test + public void testIfTypeNull() throws GitLabException { + thrown.expect(GitLabException.class); + thrown.expectMessage("Illegal argument added"); + CdfElement element = GitLabResource.getElement(null, ID, "aaa"); + } + + @Test + public void testIfNullIDIsInserted() throws GitLabException { + GitLabResource.clearMainStorage(); + CdfElement element= GitLabResource.getElement(Type.COMMIT, null, "aaa"); + Assert.assertEquals(true, GitLabResource.getMainStorage().isEmpty()); + GitLabResource.clearMainStorage(); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/IssueTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/IssueTest.java new file mode 100644 index 00000000..70dfb7d7 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/IssueTest.java @@ -0,0 +1,73 @@ +package codemetropolis.toolchain.converter.gitlab; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.model.Issue; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.List; + +public class IssueTest { + + private Issue issue; + + private static String ISSUE_STATE="opened"; + private static int ISSUE_USER_NOTES_COUNT=10; + private static int ISSUE_WEIGHT=2; + private static int ISSUE_TIME_ESTIMATE=4; + private static int ISSUE_TOTAL_TIME=11; + + @Before + public void setUp() { + issue=new Issue(); + issue.setType(Type.ISSUE); + issue.setState(ISSUE_STATE); + issue.setTimeEstimate(ISSUE_TIME_ESTIMATE); + issue.setTotalTime(ISSUE_TOTAL_TIME); + issue.setUserNotesCount(ISSUE_USER_NOTES_COUNT); + issue.setWeight(ISSUE_WEIGHT); + issue.setID("12"); + GitLabElement.setGitLabApi(null); + } + + @Test + public void testArraySize() { + List properties=issue.createProperties(); + Assert.assertEquals(6, properties.size()); + } + + @Test + public void testIfPropertiesConsistsElements() { + List properties=issue.createProperties(); + Assert.assertTrue(properties.stream().anyMatch(item->( + ISSUE_STATE.equals(item.getValue()) && + "state".equals(item.getName())&& + CdfProperty.Type.STRING.equals(item.getType()) + ))); + } + + @Test + public void testIfIssueIDIsNull() { + issue.setID(null); + Assert.assertEquals(true, issue.createProperties().isEmpty()); + } + + @Test + public void testTimeRatio() { + float t=ISSUE_TIME_ESTIMATE/(float)ISSUE_TOTAL_TIME; + String ISSUE_RATIO=Float.toString(t); + List properties=issue.createProperties(); + Assert.assertTrue(properties.stream().anyMatch(item-> + ISSUE_RATIO.equals(item.getValue()) && + "timeRatio".equals(item.getName()) && + CdfProperty.Type.FLOAT.equals(item.getType()) + )); + } + + @Test + public void testChildren() { + Assert.assertEquals(0, issue.createChildren().size()); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/MilestoneTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/MilestoneTest.java new file mode 100644 index 00000000..8e485ace --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/MilestoneTest.java @@ -0,0 +1,90 @@ +package codemetropolis.toolchain.converter.gitlab; + +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.model.Issue; +import codemetropolis.toolchain.converter.gitlab.model.Milestone; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.List; + +public class MilestoneTest { + + private Milestone milestone; + private static String MILESTONE_TITLE = "title"; + private static String MILESTONE_STATE = "state"; + + @Before + public void setUp() { + milestone = new Milestone(); + milestone.setState(MILESTONE_STATE); + milestone.setTitle(MILESTONE_TITLE); + milestone.setID("15"); + GitLabElement.setGitLabApi(null); + } + + @Test + public void testArraySize() { + List properties = milestone.createProperties(); + Assert.assertEquals(4, properties.size()); + } + + @Test + public void testIfPropertiesConsistsElements() { + List properties = milestone.createProperties(); + Assert.assertTrue(properties.stream().anyMatch(item->(MILESTONE_STATE.equals(item.getValue())) + && "state".equals(item.getName()) + && CdfProperty.Type.STRING.equals(item.getType()))); + } + + @Test + public void testIfMilestoneIDIsNull() { + milestone.setID(null); + Assert.assertEquals(true, milestone.createProperties().isEmpty()); + + } + + private Milestone addPair(Pair pair, String state) { + milestone.addChild(pair); + Issue issue = new Issue(); + issue.setID(pair.getID()); + issue.setState(state); + issue.setType(Type.ISSUE); + + try { + issue.getElement(); + } catch (GitLabException e) { + e.printStackTrace(); + } + + GitLabResource.addElement(issue); + + return milestone; + } + + @Test + public void testChildrenIssues() { + + addPair(new Pair("11", Type.ISSUE), "opened"); + addPair(new Pair("12", Type.ISSUE), "closed"); + + List properties=milestone.createProperties(); + + Assert.assertTrue(properties.stream().anyMatch(item->("0.5".equals(item.getValue())) + && "openedRatio".equals(item.getName()) && + CdfProperty.Type.FLOAT.equals(item.getType()))); + + Assert.assertTrue(properties.stream().anyMatch(item->("0.5".equals(item.getValue())) + && "closedRatio".equals(item.getName()) && + CdfProperty.Type.FLOAT.equals(item.getType()))); + + GitLabResource.clearMainStorage(); + } + + @Test + public void testChildrenMethodIfIDIsNull() { + milestone.setID(null); + Assert.assertEquals(0, milestone.createChildren().size()); + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/ProjectTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/ProjectTest.java new file mode 100644 index 00000000..1530ed27 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/ProjectTest.java @@ -0,0 +1,50 @@ +package codemetropolis.toolchain.converter.gitlab; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.List; +import org.junit.BeforeClass; +import org.junit.Test; +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.converter.gitlab.model.Project; + +public class ProjectTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @Test + public void testCreateProperties() { + GitLabElement project = new Project(); + List l = project.createProperties(); + assertEquals(true, l.size() == 0); + } + + @Test + public void testAddProperties() { + Project p = new Project(); + List list = new ArrayList<>(); + + p.setCommitCount(33); + p.setJobArtifactsSize(3); + p.setJobArtifactsSize(10); + p.setLfsObjectSize(4); + p.setStorageSize(10); + p.setApprovalsNumber(3); + p.setForksCount(4); + p.setName("namae"); + + p.addProperties(list); + + assertEquals(true, list.size() == 7); + } + + @Test + public void testCreateChildren() { + GitLabElement project = new Project(); + List pairList = project.createChildren(); + assertEquals(false, pairList.size() != 0); + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/TreeTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/TreeTest.java new file mode 100644 index 00000000..11ae31d7 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/TreeTest.java @@ -0,0 +1,39 @@ +package codemetropolis.toolchain.converter.gitlab; + +import codemetropolis.toolchain.converter.gitlab.model.Tree; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class TreeTest { + + private static Tree tree; + private static String ID = "doc---master"; + + @Before + public void setUp() { + GitLabElement.setGitLabApi(null); + tree = new Tree(); + tree.setID(ID); + } + + @Test + public void branchAndNameHasBeenSplitted() { + tree.createProperties(); + Assert.assertEquals("master", tree.getBranchName()); + Assert.assertEquals("doc", tree.getName()); + } + + @Test + public void ifIDIsNullPropertyIsEmpty() { + tree.setID(null); + Assert.assertEquals(true, tree.createProperties().isEmpty()); + } + + @Test + public void ifIDisNullPChildrenIsEmpty() { + tree.setID(null); + Assert.assertEquals(true, tree.createChildren().isEmpty()); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/UserTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/UserTest.java new file mode 100644 index 00000000..883d6ca2 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitlab/UserTest.java @@ -0,0 +1,39 @@ +package codemetropolis.toolchain.converter.gitlab; +import static org.junit.Assert.*; + +import org.junit.BeforeClass; +import org.junit.Test; + +import codemetropolis.toolchain.converter.gitlab.model.User; + +public class UserTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @Test + public void testAddingRatio() { + User user = new User(); + user.setAddingRatio(3, 0); + final float epsilon = 0.01f; + + assertEquals(true, user.getAddingRatio() == 0); + } + + @Test + public void testSetDeletionRatio() { + User user = new User(); + user.setDeletionRatio(3, 10); + final float epsilon = 0.01f; + + assertEquals(true, 0.3 - epsilon <= user.getDeletionRatio() && 0.3 + epsilon >= user.getDeletionRatio()); + } + + @Test + public void testCreateChildren() { + GitLabElement user = new User(); + assertEquals(0, user.createChildren().size()); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/ConverterLocatorTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/ConverterLocatorTest.java new file mode 100644 index 00000000..2b027b46 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/ConverterLocatorTest.java @@ -0,0 +1,31 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.HashMap; +import org.junit.Test; +import codemetropolis.toolchain.commons.cdf.converter.CdfConverter; +import codemetropolis.toolchain.converter.control.ConverterLoader; +import codemetropolis.toolchain.converter.control.ConverterType; +import codemetropolis.toolchain.converter.sonarqube.SonarQubeConverter; +import codemetropolis.toolchain.converter.sourcemeter.GraphConverter; + +public class ConverterLocatorTest { + + @Test + public void sourcemeterTest() { + CdfConverter converter = ConverterLoader.load(ConverterType.SOURCEMETER, new HashMap()); + assertEquals(GraphConverter.class, converter.getClass()); + } + + @Test + public void sonarQubeTest() { + CdfConverter converter = ConverterLoader.load(ConverterType.SONARQUBE, new HashMap()); + assertEquals(SonarQubeConverter.class, converter.getClass()); + } + + @Test + public void gitStatTest() { + CdfConverter converter = ConverterLoader.load(ConverterType.GITSTATS, new HashMap()); + assertEquals(GitStatConverter.class, converter.getClass()); + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GetLinesFromDatFilesTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GetLinesFromDatFilesTest.java new file mode 100644 index 00000000..140d7d93 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GetLinesFromDatFilesTest.java @@ -0,0 +1,33 @@ +package codemetropolis.toolchain.converter.gitstat; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; +import static org.junit.Assert.*; +public class GetLinesFromDatFilesTest { + + @Test + public void testGetLinesFromDatFiles() throws IOException { + + + String elso = ".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser\\a.dat_elso 34"; + String masodik = ".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser\\a.dat_masodik 56"; + String harmadik = ".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser\\b.dat_harmadik 65"; + String negyedik = ".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser\\b.dat_negyedik 18"; + List result = new ArrayList(); + result.add(elso); + result.add(masodik); + result.add(harmadik); + result.add(negyedik); + + List method = GitStatDatParser.getLinesFromDatFiles(".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser"); + for (String one : method) + System.out.println(one); + + assertNotEquals(null, method); + assertEquals(method, result); + + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GetPropertiesFromDatFilesTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GetPropertiesFromDatFilesTest.java new file mode 100644 index 00000000..98678173 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GetPropertiesFromDatFilesTest.java @@ -0,0 +1,44 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.Assert.*; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; +import codemetropolis.toolchain.commons.cdf.CdfProperty; + +class GetPropertiesFromDatFilesTest { + List properties; + + + @Test + void testGetPropertiesFromDatFiles() { + CdfProperty elso = new CdfProperty(".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser\\a.dat elso", "34", + CdfProperty.Type.INT); + CdfProperty masodik = new CdfProperty(".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser\\a.dat masodik", "56", + CdfProperty.Type.INT); + CdfProperty harmadik = new CdfProperty(".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser\\b.dat harmadik", + "65", CdfProperty.Type.INT); + CdfProperty negyedik = new CdfProperty(".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser\\b.dat negyedik", + "18", CdfProperty.Type.INT); + + List guardProperties = new ArrayList(); + + guardProperties.add(elso); + guardProperties.add(masodik); + guardProperties.add(harmadik); + guardProperties.add(negyedik); + + properties = GitStatDatParser.getPropertiesFromDatFiles(".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser"); + + assertNotEquals(null, properties); + for (CdfProperty propi : properties) { + + + + assertEquals(propi.getName(), guardProperties.get(properties.indexOf(propi)).getName()); + assertEquals(propi.getValue(), guardProperties.get(properties.indexOf(propi)).getValue()); + } + + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GetPropertyPreNameFromFileNameTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GetPropertyPreNameFromFileNameTest.java new file mode 100644 index 00000000..6a9a7876 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GetPropertyPreNameFromFileNameTest.java @@ -0,0 +1,56 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +class GetPropertyPreNameFromFileNameTest { + + @Test + void testGetPropertyPreNameFromFileName1() { + + String result1 = GitStatDatParser.getPropertyPreNameFromFileName("commits_by_year"); + assertEquals("commits_by_year_", result1); + } + @Test + void testGetPropertyPreNameFromFileName2() { + String result2 = GitStatDatParser.getPropertyPreNameFromFileName("commits_by_year_month"); + System.out.println(result2); + assertEquals("commits_by_year_month_", result2); + } + @Test + void testGetPropertyPreNameFromFileName3() { + String result3 = GitStatDatParser.getPropertyPreNameFromFileName("day_of_week"); + assertEquals("day_of_week_", result3); + } + @Test + void testGetPropertyPreNameFromFileName4() { + String result4 = GitStatDatParser.getPropertyPreNameFromFileName("domains"); + assertEquals("domains_", result4); + } + @Test + void testGetPropertyPreNameFromFileName5() { + String result5 = GitStatDatParser.getPropertyPreNameFromFileName("files_by_date"); + assertEquals("files_by_date_", result5); + } + @Test + void testGetPropertyPreNameFromFileName6() { + String result6 = GitStatDatParser.getPropertyPreNameFromFileName("hour_of_day"); + assertEquals("hour_of_day_", result6); + } + @Test + void testGetPropertyPreNameFromFileName7() { + String result7 = GitStatDatParser.getPropertyPreNameFromFileName("lines_of_code"); + assertEquals("lines_of_code_", result7); + } + @Test + void testGetPropertyPreNameFromFileName8() { + String result8 = GitStatDatParser.getPropertyPreNameFromFileName("month_of_year"); + assertEquals("month_of_year_", result8); + } + @Test + void testGetPropertyPreNameFromFileName9() { + String result9 = GitStatDatParser.getPropertyPreNameFromFileName(""); + assertEquals("_", result9); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GitStatHTMLParserTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GitStatHTMLParserTest.java new file mode 100644 index 00000000..1ed81147 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/GitStatHTMLParserTest.java @@ -0,0 +1,83 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import java.util.ArrayList; +import java.util.List; +import codemetropolis.toolchain.commons.cdf.CdfProperty; + +class GitStatHTMLParserTest { + + + void testGetPropertiesFromHTMLFiles() { + List props; + + CdfProperty first = new CdfProperty("First", "egy", CdfProperty.Type.STRING); + CdfProperty second = new CdfProperty("Second", "Masodik2 masodik2", CdfProperty.Type.STRING); + CdfProperty third = new CdfProperty("t h i r d", "Harmadik?? 2.3", CdfProperty.Type.STRING); + CdfProperty fourth = new CdfProperty("fourth", "", CdfProperty.Type.STRING); + + List guardProperties = new ArrayList(); + + guardProperties.add(first); + guardProperties.add(second); + guardProperties.add(third); + guardProperties.add(fourth); + + props = GitStatHTMLParser.getPropertiesFromHTMLFiles(".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser"); + + assertNotEquals(null, props); + for (CdfProperty prop : props) { + assertEquals(prop.getName(), guardProperties.get(props.indexOf(prop)).getName()); + assertEquals(prop.getValue(), guardProperties.get(props.indexOf(prop)).getValue()); + } + } + + + void testGetLinesFromHTMLFiles() { + List expectedResult = new ArrayList(); + expectedResult.add(""); + expectedResult.add(""); + expectedResult.add(""); + expectedResult.add(""); + expectedResult.add("

GitStats - RF2

"); + expectedResult.add("
"); + expectedResult.add("
    "); + expectedResult.add("
  • General
  • "); + expectedResult.add("
  • Activity
  • "); + expectedResult.add("
  • Authors
  • "); + expectedResult.add("
  • Files
  • "); + expectedResult.add("
  • Lines
  • "); + expectedResult.add("
  • Tags
  • "); + expectedResult.add("
"); + expectedResult.add("
"); + expectedResult.add("
"); + expectedResult.add("
First
"); + expectedResult.add("
egy
"); + expectedResult.add("
Second
"); + expectedResult.add("
Masodik2 masodik2
"); + expectedResult.add("
t h i r d
"); + expectedResult.add("
Harmadik?? 2.3
"); + expectedResult.add("
fourth
"); + expectedResult.add("
"); + expectedResult.add("
"); + expectedResult.add(" "); + + List result = GitStatHTMLParser.getLinesFromHTMLFiles(".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource\\TestDatParser"); + + + assertNotEquals(null, result); + assertEquals(result, expectedResult); + } + + + void testIsNumber() { + assertEquals(true, GitStatHTMLParser.isNumber("232674627")); + assertEquals(true, GitStatHTMLParser.isNumber("0")); + assertEquals(true, GitStatHTMLParser.isNumber("-25646416")); + assertEquals(false, GitStatHTMLParser.isNumber("543apple32. Birne782!")); + assertEquals(false, GitStatHTMLParser.isNumber("55546,545")); + assertEquals(false, GitStatHTMLParser.isNumber("45.46546")); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/Test_CdfTreeBuilder_createTreeFromMap.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/Test_CdfTreeBuilder_createTreeFromMap.java new file mode 100644 index 00000000..54ca871a --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/Test_CdfTreeBuilder_createTreeFromMap.java @@ -0,0 +1,63 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.commons.cdf.CdfTree; + +public class Test_CdfTreeBuilder_createTreeFromMap { + + public Map> map; + public List list; + + public void initValid() { + list = new ArrayList<>(); + list.add(new CdfProperty("teszt1", "teszt2", CdfProperty.Type.INT)); + map = new HashMap<>(); + map.put(new CdfElement(), list); + } + + public void initEmpty() { + list = new ArrayList<>(); + map = new HashMap<>(); + map.put(new CdfElement(), list); + } + + @Test + public void createTreeFromMapValid() { + initValid(); + CdfTree tree = CdfTreeBuilder.createTreeFromMap(map); + assertNotNull(tree); + assertNotNull(tree.getRoot()); + assertEquals("teszt2", tree.getRoot().getProperty("teszt1").getValue()); + assertEquals(CdfProperty.Type.INT, tree.getRoot().getProperty("teszt1").getType()); + } + + @Test + public void createTreeFromMapEmpty() { + initEmpty(); + CdfTree tree = CdfTreeBuilder.createTreeFromMap(map); + assertNotNull(tree); + assertNull(tree.getRoot()); + } + + @Test + public void createTreeFromMapEmpty2() { + CdfTree tree = CdfTreeBuilder.createTreeFromMap(new HashMap>()); + assertNotNull(tree); + assertNull(tree.getRoot()); + } + + @Test + public void createTreeFromMapNukk() { + CdfTree tree = CdfTreeBuilder.createTreeFromMap(null); + assertNotNull(tree); + } +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/Test_GitStatConverter_createElements.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/Test_GitStatConverter_createElements.java new file mode 100644 index 00000000..e75794bb --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/Test_GitStatConverter_createElements.java @@ -0,0 +1,48 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.Assert.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.HashMap; +import org.junit.jupiter.api.Test; +import codemetropolis.toolchain.commons.cdf.CdfTree; +import codemetropolis.toolchain.commons.cdf.converter.CdfConverter; +import codemetropolis.toolchain.commons.exceptions.CodeMetropolisException; + +public class Test_GitStatConverter_createElements { + + CdfConverter converter = new GitStatConverter(new HashMap()); + + @Test + public void testCreateElementsEmpty() throws CodeMetropolisException { + CdfTree tree = converter.createElements(""); + assertNotEquals(null, tree); + assertEquals("root", tree.getRoot().getName()); + assertEquals("root", tree.getRoot().getType()); + } + + @Test + public void testCreateElementsValid() throws CodeMetropolisException { + CdfTree tree = converter.createElements(".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource"); + assertNotEquals(null, tree); + assertEquals("root", tree.getRoot().getName()); + assertEquals("root", tree.getRoot().getType()); + } + + @Test + public void testCreateElementsInvalid() throws CodeMetropolisException { + CdfTree tree = converter.createElements("/%=)(=)!(=+�)(=1111213__+)('(+1213414'"); + assertNotEquals(null, tree); + assertEquals("root", tree.getRoot().getName()); + assertEquals("root", tree.getRoot().getType()); + } + + @Test + public void testCreateElementsNull() throws CodeMetropolisException { + CdfTree tree = converter.createElements(null); + assertNotEquals(null, tree); + assertEquals("root", tree.getRoot().getName()); + assertEquals("root", tree.getRoot().getType()); + } + + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/Test_PropertyCollector_collect.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/Test_PropertyCollector_collect.java new file mode 100644 index 00000000..3bd63b93 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/Test_PropertyCollector_collect.java @@ -0,0 +1,34 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.Assert.assertNotNull; +import java.util.List; +import org.junit.Test; +import codemetropolis.toolchain.commons.cdf.CdfProperty; + +public class Test_PropertyCollector_collect { + + @Test + public void collectValid() { + List list = PropertyCollector.collect(".\\src\\test\\java\\codemetropolis\\toolchain\\converter\\gitstat\\test_resource"); + assertNotNull(list); + } + /* + @Test + public void collectInvalid() { + List list = PropertyCollector.collect("12345__2132124*"); + assertNotNull(list); + } + */ + @Test + public void collectNull() { + List list = PropertyCollector.collect(null); + assertNotNull(list); + } + + @Test + public void collectEmpty() { + List list = PropertyCollector.collect(""); + assertNotNull(list); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/TreeBuilderAddPropertiesTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/TreeBuilderAddPropertiesTest.java new file mode 100644 index 00000000..187be2f6 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/TreeBuilderAddPropertiesTest.java @@ -0,0 +1,37 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.commons.cdf.CdfTree; + +public class TreeBuilderAddPropertiesTest { + + @Test + public void testNormal() { + CdfProperty property = new CdfProperty("Property1", "Value1", CdfProperty.Type.INT); + CdfElement element = new CdfElement(); + CdfTree tree = new CdfTree(null); + CdfTreeBuilder.addPropertyToElement(element, property, tree); + assertEquals(element, tree.getRoot()); + assertTrue(tree.getRoot().getProperty("Property1").getValue().equals("Value1")); + } + + @Test + public void testAbnormal() { + Exception ex = null; + try { + CdfTreeBuilder.addPropertyToElement(null, null, null); + } + catch (Exception error) + { + ex = error; + } + // no exception + assertNull(ex); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/TreeBuilderCreateTreeTest.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/TreeBuilderCreateTreeTest.java new file mode 100644 index 00000000..96f98e4e --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/TreeBuilderCreateTreeTest.java @@ -0,0 +1,39 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.commons.cdf.CdfTree; + +public class TreeBuilderCreateTreeTest { + + @Test + public void normalTest() { + CdfTree tree = null; + CdfElement element = new CdfElement(); + List properties = new ArrayList(); + properties.add(new CdfProperty("Property1", "Value1", CdfProperty.Type.INT)); + tree = CdfTreeBuilder.createTree(element, properties); + assertNotNull(tree); + assertTrue(tree.getElements().size() > 0); + assertEquals("root", tree.getRoot().getName()); + assertEquals("root", tree.getRoot().getType()); + } + + @Test + public void abnormalTest() { + CdfTree tree = null; + CdfElement element = null; + List properties = new ArrayList(); + tree = CdfTreeBuilder.createTree(element, properties); + assertNotNull(tree); + assertTrue(tree.getElements().size() > 0); + assertEquals("root", tree.getRoot().getName()); + assertEquals("root", tree.getRoot().getType()); + } +} diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/UnitGitStatFileHelperSearchFiles.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/UnitGitStatFileHelperSearchFiles.java new file mode 100644 index 00000000..274fc081 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/UnitGitStatFileHelperSearchFiles.java @@ -0,0 +1,36 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.List; +import org.junit.Test; + +public class UnitGitStatFileHelperSearchFiles { + + + @Test + public void invalidParam() { + List list = null; + list = GitStatFileHelper.searchForFile("abcd1234", null); + assertEquals(0, list.size()); + assertNotNull(list); + } + + @Test + public void nullParam() { + List list = null; + list = GitStatFileHelper.searchForFile(null, null); + assertEquals(0, list.size()); + assertNotNull(list); + } + + @Test + public void correctParam() { + List list = null; + list = GitStatFileHelper.searchForFile("C:/maven/", "txt"); + assertNotNull(list); + assertEquals("c:\\maven\\readme.txt".toUpperCase(), list.get(0).toUpperCase()); + } + + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/UnitGitsStatFileHelperLines.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/UnitGitsStatFileHelperLines.java new file mode 100644 index 00000000..180b9c6c --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/UnitGitsStatFileHelperLines.java @@ -0,0 +1,53 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import java.io.IOException; +import java.util.List; +import org.junit.Test; + +/** + * + * @author Radics Ott� + * + */ +public class UnitGitsStatFileHelperLines { + + @Test + public void invalidParam() { + List list = null; + try { + list = GitStatFileHelper.getLinesFromFile("abcd1234"); + } catch (IOException e) { + e.printStackTrace(); + } + + assertNull(list); + + } + + @Test + public void nullParam() { + List list = null; + try { + list = GitStatFileHelper.getLinesFromFile(null); + } catch (IOException e) { + e.printStackTrace(); + } + + assertNull(list); + } + + @Test + public void correctParam() { + List list = null; + try { + list = GitStatFileHelper.getLinesFromFile("C:/maven/readme.txt"); + } catch (IOException e) { + e.printStackTrace(); + } + + assertNotNull(list); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/UnitTreeBuilderAddPropertiesToElement.java b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/UnitTreeBuilderAddPropertiesToElement.java new file mode 100644 index 00000000..8edd1be5 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/UnitTreeBuilderAddPropertiesToElement.java @@ -0,0 +1,34 @@ +package codemetropolis.toolchain.converter.gitstat; + +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; +import codemetropolis.toolchain.commons.cdf.CdfElement; +import codemetropolis.toolchain.commons.cdf.CdfProperty; +import codemetropolis.toolchain.commons.cdf.CdfTree; + +public class UnitTreeBuilderAddPropertiesToElement { + + + @Test + public void invalidParam() { + List list = new ArrayList(); + CdfTree tree = new CdfTree(new CdfElement()); + CdfTreeBuilder.addPropertiesToElement(new CdfElement(), list, tree); + assertEquals(1, tree.getElements().size()); + assertNotNull(tree.getRoot()); + } + + @Test + public void correctParam() { + List list = new ArrayList(); + list.add(new CdfProperty("name", "value", CdfProperty.Type.INT)); + CdfTree tree = new CdfTree(null); + CdfTreeBuilder.addPropertiesToElement(new CdfElement(), list, tree); + assertEquals(CdfProperty.Type.INT, tree.getRoot().getProperty("name").getType()); + assertNotNull(tree.getRoot()); + } + +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/TestDatParser/a.dat b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/TestDatParser/a.dat new file mode 100644 index 00000000..5a5a738d --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/TestDatParser/a.dat @@ -0,0 +1,2 @@ +elso 34 +masodik 56 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/TestDatParser/b.dat b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/TestDatParser/b.dat new file mode 100644 index 00000000..3a8dbeea --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/TestDatParser/b.dat @@ -0,0 +1,2 @@ +harmadik 65 +negyedik 18 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/TestHTMLParser/TestHTML.html b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/TestHTMLParser/TestHTML.html new file mode 100644 index 00000000..aab22bbf --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/TestHTMLParser/TestHTML.html @@ -0,0 +1,26 @@ + + + + +

GitStats - RF2

+ +
+
First
+
egy
+
Second
+
Masodik2 masodik2
+
t h i r d
+
Harmadik?? 2.3
+
fourth
+
+
+ \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/activity.html b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/activity.html new file mode 100644 index 00000000..712c77fa --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/activity.html @@ -0,0 +1,616 @@ + + + + + GitStats - RF2 + + + + + +

Activity

+ +

Weekly activity

+

Last 32 weeks

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
3231302928272625242322212019181716151413121110987654321
+

Hour of Day

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Hour01234567891011121314151617181920212223
Commits0000000027177649883000302
%0.000.000.000.000.000.000.000.002.639.2122.379.217.895.2611.8410.5310.533.950.000.000.003.950.002.63
Hour of Day +

Day of Week

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DayTotal (%)
18 (10.53%)
26 (7.89%)
310 (13.16%)
431 (40.79%)
516 (21.05%)
62 (2.63%)
73 (3.95%)
Day of Week +

Hour of Week

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Weekday01234567891011121314151617181920212223
11121111
211121
312313
41310225422
523411311
611
712
+

Month of Year

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthCommits (%)
17 (9.21 %)
232 (42.11 %)
325 (32.89 %)
412 (15.79 %)
50 (0.00 %)
60 (0.00 %)
70 (0.00 %)
80 (0.00 %)
90 (0.00 %)
100 (0.00 %)
110 (0.00 %)
120 (0.00 %)
Month of Year +

Commits by + year/month

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthCommits
2017-022
2016-0411
2016-0325
2016-0230
2016-017
2014-041
Commits by year/month +

Commits by Year

+
+ + + + + + + + + + + + + + + + +
YearCommits (% of all)
20172 (2.63%)
201673 (96.05%)
20141 (1.32%)
Commits by Year +

Commits by Timezone

+ + + + + + + + + + + + + +
TimezoneCommits
+010056
+020020
+ \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/arrow-down.gif b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/arrow-down.gif new file mode 100644 index 00000000..997f02f6 Binary files /dev/null and b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/arrow-down.gif differ diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/arrow-none.gif b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/arrow-none.gif new file mode 100644 index 00000000..d011a499 Binary files /dev/null and b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/arrow-none.gif differ diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/arrow-up.gif b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/arrow-up.gif new file mode 100644 index 00000000..15eabb35 Binary files /dev/null and b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/arrow-up.gif differ diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/authors.html b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/authors.html new file mode 100644 index 00000000..86df0921 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/authors.html @@ -0,0 +1,167 @@ + + + + + GitStats - RF2 + + + + + +

Authors

+ +

List of Authors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AuthorCommits (%)+ lines- linesFirst commitLast commitAgeActive days# by commits
Attila Szabolics60 (78.95%)583522152016-01-172016-04-1487 days, 13:01:01221
berika11 (14.47%)14873492016-02-022016-03-0430 days, 23:03:5272
Gergő Balogh4 (5.26%)862014-04-082017-02-161045 days, 5:33:2033
Balogh Gergõ1 (1.32%)002016-01-182016-01-180:00:0014
+

Author of Month

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthAuthorCommits (%)Next top 5
2017-02Gergő Balogh2 (100.00% of 2)
2016-04Attila Szabolics11 (100.00% of 11)
2016-03Attila Szabolics22 (88.00% of 25)berika
2016-02Attila Szabolics22 (73.33% of 30)berika
2016-01Attila Szabolics5 (71.43% of 7)Gergő Balogh, Balogh Gergõ
2014-04Gergő Balogh1 (100.00% of 1)
+

Author of Year

+ + + + + + + + + + + + + + + + + + + + + + + + + +
YearAuthorCommits (%)Next top 5
2017Gergő Balogh2 (100.00% of 2)
2016Attila Szabolics60 (82.19% of 73)berika, Gergő Balogh, Balogh Gergõ
2014Gergő Balogh1 (100.00% of 1)
+

Commits by Domains

+
+ + + + + + + + + + + + +
DomainsTotal (%)
inf.u-szeged.hu72 (94.74%)
gmail.com4 (5.26%)
Commits by Domains + \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year.dat b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year.dat new file mode 100644 index 00000000..31865f5a --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year.dat @@ -0,0 +1,3 @@ +2014 1 +2016 73 +2017 2 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year.plot b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year.plot new file mode 100644 index 00000000..47cf23cf --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year.plot @@ -0,0 +1,10 @@ +set terminal svg +set size 1.0,0.5 + +set output 'commits_by_year.svg' +unset key +set xtics 1 rotate by 90 +set grid y +set ylabel "Commits" +set yrange [0:] +plot 'commits_by_year.dat' using 1:2:(0.5) w boxes fs solid \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year_month.dat b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year_month.dat new file mode 100644 index 00000000..0876773f --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year_month.dat @@ -0,0 +1,6 @@ +2014-04 1 +2016-01 7 +2016-02 30 +2016-03 25 +2016-04 11 +2017-02 2 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year_month.plot b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year_month.plot new file mode 100644 index 00000000..ab421934 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/commits_by_year_month.plot @@ -0,0 +1,13 @@ +set terminal svg +set size 1.0,0.5 + +set output 'commits_by_year_month.svg' +unset key +set xdata time +set timefmt "%Y-%m" +set format x "%Y-%m" +set xtics rotate by 90 15768000 +set bmargin 5 +set grid y +set ylabel "Commits" +plot 'commits_by_year_month.dat' using 1:2:(0.5) w boxes fs solid \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/day_of_week.dat b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/day_of_week.dat new file mode 100644 index 00000000..759470fe --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/day_of_week.dat @@ -0,0 +1,7 @@ +1 8 +2 6 +3 10 +4 31 +5 16 +6 2 +7 3 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/day_of_week.plot b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/day_of_week.plot new file mode 100644 index 00000000..de5f4b64 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/day_of_week.plot @@ -0,0 +1,10 @@ +set terminal svg +set size 1.0,0.5 + +set output 'day_of_week.svg' +unset key +set xrange [0.5:7.5] +set xtics 1 +set grid y +set ylabel "Commits" +plot 'day_of_week.dat' using 1:2:(0.5) w boxes fs solid \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/domains.dat b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/domains.dat new file mode 100644 index 00000000..eb675ace --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/domains.dat @@ -0,0 +1,2 @@ +inf.u-szeged.hu 1 72 +gmail.com 2 4 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/domains.plot b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/domains.plot new file mode 100644 index 00000000..6951f2cd --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/domains.plot @@ -0,0 +1,9 @@ +set terminal svg +set size 1.0,0.5 + +set output 'domains.svg' +unset key +unset xtics +set grid y +set ylabel "Commits" +plot 'domains.dat' using 2:3:(0.5) with boxes fs solid, '' using 2:3:1 with labels rotate by 45 offset 0,1 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/files.html b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/files.html new file mode 100644 index 00000000..4e4631b6 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/files.html @@ -0,0 +1,107 @@ + + + + + GitStats - RF2 + + + + + +

Files

+ +
+
Total files
+
164
+
Total lines
+
4205
+
Average file size
+
2564.02 bytes
+
+

File count by date

+ Files by Date +

Extensions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExtensionFiles (%)Lines (%)Lines/file
6 (3.66%)30 (0.71%)5
classpath5 (3.05%)178 (4.23%)35
csv1 (0.61%)170 (4.04%)170
jar2 (1.22%)355 (8.44%)177
java122 (74.39%)7925 (188.47%)64
md1 (0.61%)8 (0.19%)8
project6 (3.66%)132 (3.14%)22
properties2 (1.22%)93 (2.21%)46
txt4 (2.44%)864 (20.55%)216
xml13 (7.93%)2856 (67.92%)219
xsd1 (0.61%)49 (1.17%)49
+ \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/files_by_date.dat b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/files_by_date.dat new file mode 100644 index 00000000..b1da0360 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/files_by_date.dat @@ -0,0 +1,46 @@ +2014-04-08 1 +2016-01-11 1 +2016-01-17 115 +2016-01-18 111 +2016-01-18 115 +2016-01-18 117 +2016-02-02 130 +2016-02-04 130 +2016-02-04 131 +2016-02-05 130 +2016-02-17 131 +2016-02-22 131 +2016-02-22 132 +2016-02-23 131 +2016-02-24 131 +2016-02-24 136 +2016-02-25 131 +2016-02-25 138 +2016-02-25 139 +2016-02-26 139 +2016-02-27 139 +2016-02-27 142 +2016-02-28 142 +2016-03-01 141 +2016-03-01 142 +2016-03-04 143 +2016-03-09 145 +2016-03-11 145 +2016-03-11 146 +2016-03-16 147 +2016-03-16 149 +2016-03-16 152 +2016-03-17 152 +2016-03-17 153 +2016-03-18 153 +2016-03-30 157 +2016-03-31 158 +2016-03-31 159 +2016-03-31 160 +2016-03-31 162 +2016-04-01 162 +2016-04-04 163 +2016-04-07 163 +2016-04-08 163 +2016-04-14 163 +2017-02-16 163 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/files_by_date.plot b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/files_by_date.plot new file mode 100644 index 00000000..5c5d15f7 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/files_by_date.plot @@ -0,0 +1,14 @@ +set terminal svg +set size 1.0,0.5 + +set output 'files_by_date.svg' +unset key +set xdata time +set timefmt "%Y-%m-%d" +set format x "%Y-%m-%d" +set grid y +set ylabel "Files" +set xtics rotate by 90 +set ytics autofreq +set bmargin 6 +plot 'files_by_date.dat' using 1:2 w steps \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/gitstats.cache b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/gitstats.cache new file mode 100644 index 00000000..33ef9b0e Binary files /dev/null and b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/gitstats.cache differ diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/gitstats.css b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/gitstats.css new file mode 100644 index 00000000..07922e6a --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/gitstats.css @@ -0,0 +1,142 @@ +/** + * GitStats - default style + */ + body{ + color: black; + background-color: #dfd; +} + +dt{ + font-weight: bold; + float: left; + margin-right: 1em; +} + +dt:after{ + content: ': '; +} + +dd{ + display: block; + clear: left; +} + +table{ + border: 1px solid black; + border-collapse: collapse; + font-size: 80%; + margin-bottom: 1em; +} + +table.noborders{ + border: none; +} + +table.noborders td{ + border: none; +} + +.vtable{ + float: right; + clear: both; +} + +table.tags td{ + vertical-align: top; +} + +th{ + background-color: #ddf; +} + +th a{ + text-decoration: none; +} + +tr:hover{ + background-color: #ddf; +} + +td{ + border: 1px solid black; + padding: 0.2em; + padding-left: 0.3em; + padding-right: 0.2em; +} + +/* Navigation bar; tabbed style */ +.nav{ + border-bottom: 1px solid black; + padding: 0.3em; +} + +.nav ul{ + list-style-type: none; + display: inline; + margin: 0; + padding: 0; +} + +.nav li{ + display: inline; +} + +.nav li a{ + padding: 0.3em; + text-decoration: none; + color: black; + border: 1px solid black; + margin: 0.5em; + background-color: #ddf; +} + +.nav li a:hover{ + background-color: #ddd; + border-bottom: 1px solid #ddf; +} + +img{ + border: 1px solid black; + padding: 0.5em; + background-color: white; +} + +th img{ + border: 0px; + padding: 0px; + background-color: #ddf; +} + +h1 a, +h2 a{ + color: black; + text-decoration: none; +} + +h1:hover a:after, +h2:hover a:after{ + content: '¶'; + color: #555; +} + +h1{ + font-size: x-large; +} + +h2{ + background-color: #564; + border: 1px solid black; + padding-left: 0.5em; + padding-right: 0.5em; + color: white; + font-size: large; + clear: both; +} + +h2 a{ + color: white; +} + +.moreauthors{ + font-size: 80%; +} \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/hour_of_day.dat b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/hour_of_day.dat new file mode 100644 index 00000000..cbf4a37c --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/hour_of_day.dat @@ -0,0 +1,24 @@ +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 2 +10 7 +11 17 +12 7 +13 6 +14 4 +15 9 +16 8 +17 8 +18 3 +19 0 +20 0 +21 0 +22 3 +23 0 +24 2 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/hour_of_day.plot b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/hour_of_day.plot new file mode 100644 index 00000000..2b850a1c --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/hour_of_day.plot @@ -0,0 +1,10 @@ +set terminal svg +set size 1.0,0.5 + +set output 'hour_of_day.svg' +unset key +set xrange [0.5:24.5] +set xtics 4 +set grid y +set ylabel "Commits" +plot 'hour_of_day.dat' using 1:2:(0.5) w boxes fs solid \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/index.html b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/index.html new file mode 100644 index 00000000..23967085 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/index.html @@ -0,0 +1,42 @@ + + + + + GitStats - RF2 + + + + + +

GitStats - RF2

+ +
+
Project name
+
RF2
+
Generated
+
2018-03-22 09:49:02 (in 26 seconds)
+
Generator
+
GitStats (version 0432da3)
+
Report Period
+
2014-04-08 09:25:21 to 2017-02-16 14:58:41
+
Age
+
1046 days, 30 active days (2.87%)
+
Total Files
+
164
+
Total Lines of Code
+
4205 (6412 added, 2207 removed)
+
Total Commits
+
76 (average 2.5 commits per active day, 0.1 per all days)
+
Authors
+
4
+
+ \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/lines.html b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/lines.html new file mode 100644 index 00000000..3143be60 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/lines.html @@ -0,0 +1,28 @@ + + + + + GitStats - RF2 + + + + + +

Lines

+ +
+
Total lines
+
4205
+
+

Lines of Code

+ + \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/lines_of_code.dat b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/lines_of_code.dat new file mode 100644 index 00000000..9ad76ad2 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/lines_of_code.dat @@ -0,0 +1,76 @@ +1396941921 0 +1452504811 0 +1453060938 0 +1453068424 0 +1453102121 0 +1453104098 -217 +1453126093 -217 +1453130990 -217 +1454405253 442 +1454427553 434 +1454576709 434 +1454579063 462 +1454582958 431 +1454594118 401 +1454597133 415 +1454598586 415 +1454678086 415 +1454679615 415 +1455709118 518 +1456136886 582 +1456141544 2837 +1456242593 2874 +1456316164 2987 +1456327721 2990 +1456392069 3098 +1456392194 3098 +1456393248 3098 +1456409001 3076 +1456412351 3076 +1456416701 3062 +1456418280 3062 +1456484025 3074 +1456485496 3074 +1456489011 3074 +1456519663 3106 +1456580378 3156 +1456603758 3256 +1456696878 3276 +1456842492 3276 +1456849729 3399 +1457080285 3548 +1457533152 3595 +1457703860 3662 +1457707720 3713 +1458128143 3727 +1458131273 3739 +1458132805 3795 +1458141379 3795 +1458142029 3795 +1458204586 3814 +1458205356 3813 +1458222783 3880 +1458226862 3944 +1458292814 3944 +1458297739 3944 +1459327406 3921 +1459413328 3989 +1459414771 4010 +1459416626 4010 +1459418656 4058 +1459420073 4058 +1459426128 4063 +1459430029 4093 +1459498049 4088 +1459499948 4088 +1459502395 4106 +1459503115 4106 +1459758884 4185 +1460016249 4185 +1460101920 4197 +1460616408 4197 +1460619190 4204 +1460619943 4205 +1460620999 4205 +1487253511 4205 +1487253521 4205 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/lines_of_code.plot b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/lines_of_code.plot new file mode 100644 index 00000000..c925b16f --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/lines_of_code.plot @@ -0,0 +1,13 @@ +set terminal svg +set size 1.0,0.5 + +set output 'lines_of_code.svg' +unset key +set xdata time +set timefmt "%s" +set format x "%Y-%m-%d" +set grid y +set ylabel "Lines" +set xtics rotate by 90 +set bmargin 6 +plot 'lines_of_code.dat' using 1:2 w lines \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/month_of_year.dat b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/month_of_year.dat new file mode 100644 index 00000000..1a3e7f9f --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/month_of_year.dat @@ -0,0 +1,12 @@ +1 7 +2 32 +3 25 +4 12 +5 0 +6 0 +7 0 +8 0 +9 0 +10 0 +11 0 +12 0 \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/month_of_year.plot b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/month_of_year.plot new file mode 100644 index 00000000..bb2338c4 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/month_of_year.plot @@ -0,0 +1,10 @@ +set terminal svg +set size 1.0,0.5 + +set output 'month_of_year.svg' +unset key +set xrange [0.5:12.5] +set xtics 1 +set grid y +set ylabel "Commits" +plot 'month_of_year.dat' using 1:2:(0.5) w boxes fs solid \ No newline at end of file diff --git a/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/sortable.js b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/sortable.js new file mode 100644 index 00000000..006a12f8 --- /dev/null +++ b/sources/toolchain/converter/src/test/java/codemetropolis/toolchain/converter/gitstat/test_resource/sortable.js @@ -0,0 +1,340 @@ +/* +Table sorting script by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/. +Based on a script from http://www.kryogenix.org/code/browser/sorttable/. +Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html . + +Copyright (c) 1997-2007 Stuart Langridge, Joost de Valk. + +Version 1.5.7 + */ + +/* You can change these values */ +var image_path = ""; +var image_up = "arrow-up.gif"; +var image_down = "arrow-down.gif"; +var image_none = "arrow-none.gif"; +var europeandate = true; +var alternate_row_colors = true; + +/* Don't change anything below this unless you know what you're doing */ +addEvent(window, "load", sortables_init); + +var SORT_COLUMN_INDEX; +var thead = false; + +function sortables_init() { + // Find all tables with class sortable and make them sortable + if (! document.getElementsByTagName) return; + tbls = document.getElementsByTagName("table"); + for (ti = 0; ti < tbls.length; ti++) { + thisTbl = tbls[ti]; + if (((' ' + thisTbl.className + ' ').indexOf("sortable") != -1) && (thisTbl.id)) { + ts_makeSortable(thisTbl); + } + } +} + +function ts_makeSortable(t) { + if (t.rows && t.rows.length > 0) { + if (t.tHead && t.tHead.rows.length > 0) { + var firstRow = t.tHead.rows[t.tHead.rows.length -1]; + thead = true; + } else { + var firstRow = t.rows[0]; + } + } + if (! firstRow) return; + + // We have a first row: assume it's the header, and make its contents clickable links + for (var i = 0; i < firstRow.cells.length; i++) { + var cell = firstRow.cells[i]; + var txt = ts_getInnerText(cell); + if (cell.className != "unsortable" && cell.className.indexOf("unsortable") == -1) { + cell.innerHTML = '' + txt + '  ↓'; + } + } + if (alternate_row_colors) { + alternate(t); + } +} + +function ts_getInnerText(el) { + if (typeof el == "string") return el; + if (typeof el == "undefined") { + return el + }; + if (el.innerText) return el.innerText; + //Not needed but it is faster + var str = ""; + + var cs = el.childNodes; + var l = cs.length; + for (var i = 0; i < l; i++) { + switch (cs[i].nodeType) { + case 1: //ELEMENT_NODE + str += ts_getInnerText(cs[i]); + break; + case 3: //TEXT_NODE + str += cs[i].nodeValue; + break; + } + } + return str; +} + +function ts_resortTable(lnk, clid) { + var span; + for (var ci = 0; ci < lnk.childNodes.length; ci++) { + if (lnk.childNodes[ci].tagName && lnk.childNodes[ci].tagName.toLowerCase() == 'span') span = lnk.childNodes[ci]; + } + var spantext = ts_getInnerText(span); + var td = lnk.parentNode; + var column = clid || td.cellIndex; + var t = getParent(td, 'TABLE'); + // Work out a type for the column + if (t.rows.length <= 1) return; + var itm = ""; + var i = 1; + while (itm == "" && i < t.tBodies[0].rows.length) { + var itm = ts_getInnerText(t.tBodies[0].rows[i].cells[column]); + itm = trim(itm); + if (itm.substr(0, 4) == " + + jakarta.xml.bind + jakarta.xml.bind-api + 3.0.0 + + + com.sun.xml.bind + jaxb-impl + 3.0.0 + runtime + - javax.xml.bind - jaxb-api - 2.1 + junit + junit diff --git a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/control/MappingController.java b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/control/MappingController.java index 6a69d02c..270cf14e 100644 --- a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/control/MappingController.java +++ b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/control/MappingController.java @@ -8,10 +8,12 @@ import java.util.Map; import java.util.Stack; import java.util.UUID; +import java.util.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import codemetropolis.toolchain.commons.cmxml.Point; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -39,6 +41,7 @@ public class MappingController { private boolean skipInvalidStructures; private Stack buildableStack = new Stack<>(); private Mapping mapping; + protected int metricValue; public MappingController(Mapping mapping) { this(mapping, 1.0, false); @@ -49,7 +52,7 @@ public MappingController(Mapping mapping, double scale, boolean skipInvalidStruc this.scale = scale; this.skipInvalidStructures = skipInvalidStructures; } - + //ez a rész építi fel az első root buildable-t public void createBuildablesFromCdf(String filename) throws CdfReaderException { attributesByBuildables.clear(); @@ -81,7 +84,7 @@ public void createBuildablesFromCdf(String filename) throws CdfReaderException { throw new CdfReaderException(e); } } - + //sztem ez linkeli össze a buildables tageket a metrikekkel, amik a property adatok voltak public BuildableTree linkBuildablesToMetrics() { List linkings = mapping.getLinkings(); @@ -90,6 +93,7 @@ public BuildableTree linkBuildablesToMetrics() { for(Map.Entry> entry : attributesByBuildables.entrySet()) { Buildable b = entry.getKey(); + //itt kéri ki sztem a propertykből a valuet Map attributes = entry.getValue(); Linking linking = null; @@ -105,6 +109,12 @@ public BuildableTree linkBuildablesToMetrics() { } for(Binding binding : linking.getBindings()) { + if ("ChildClasses".equals(binding.getFrom()) || "AttributeClasses".equals(binding.getFrom()) + || ("tunnel".equals(binding.getTo()) && (!"ChildClasses".equals(binding.getFrom()) || !"AttributeClasses".equals(binding.getFrom()))) + || ("bridge".equals(binding.getTo()) && (!"ChildClasses".equals(binding.getFrom()) || !"AttributeClasses".equals(binding.getFrom())))) { + continue; + } + String variableId = binding.getVariableId(); if(variableId != null) { String resource = resources.get(variableId); @@ -136,19 +146,39 @@ public BuildableTree linkBuildablesToMetrics() { prepareBuildables(buildableTree); return buildableTree; } - + //eddig legenerálta a buildable-eket, gyermekeket is, és hozzárendelte a metric értékeket. + //itt sztem propertyként a buildable position és size tagjára gondol, azoknak állítja be az értéket private void setProperty(Buildable b, String propertyName, Object value, boolean adjustSize) { switch(propertyName) { case "height": case "width": case "length": + case "BuiltMetric1": + case "BuiltMetric2": + case "BuiltMetric3": + value = Conversion.toInt(value); - if(adjustSize) value = Conversion.toInt(MIN_SIZE + (int)value * scale); + metricValue=(int)value; + + if(adjustSize){ value = Conversion.toInt(MIN_SIZE + (int)value * scale);} break; } + //sztem itt állítja be ténylegesen az értékeket switch(propertyName) { + case "BuiltMetric1": + b.setBuiltMetric1(metricValue); + b.addAttribute(propertyName, String.valueOf(metricValue)); + break; + case "BuiltMetric2": + b.setBuiltMetric2(metricValue); + b.addAttribute(propertyName, String.valueOf(metricValue)); + break; + case "BuiltMetric3": + b.setBuiltMetric3(metricValue); + b.addAttribute(propertyName, String.valueOf(metricValue)); + break; case "height": b.setSizeY((int)value); break; @@ -162,10 +192,10 @@ private void setProperty(Buildable b, String propertyName, Object value, boolean b.addAttribute(propertyName, String.valueOf(value)); } } - + //itt állítja be sztem a gyermek buildables attribútumait private void setChildren(Buildable buildable, Element element){ if(buildableStack.isEmpty()){ - buildable.setCdfNames(buildable.getName()); + buildable.setCdfNames(buildable.getName()); //itt állítja be a buildable name attribútumát } else { Buildable top = buildableStack.peek(); if(buildable.getCdfNames() == null){ @@ -174,6 +204,7 @@ private void setChildren(Buildable buildable, Element element){ buildable.setCdfNames(sb.toString()); } } + //itt rakja össze a buildables gyermekek sorrendjét buildableStack.add(buildable); Node children = element.getChildNodes().item(1); NodeList childrenNodes = children.getChildNodes(); @@ -204,9 +235,17 @@ private void setAttributes(Buildable buildable, Element element){ } attributesByBuildables.put(buildable, attributes); } - + //itt szedi össze konkrétan a buildable az attribútumainak értékeit private Buildable createBuildable(Element element) { - String id = UUID.randomUUID().toString(); + String id = null; + NodeList nodeList = element.getElementsByTagName("property"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node n = nodeList.item(i); + if (n instanceof Element && "source_id".equals(((Element) n).getAttribute("name"))) { + id = ((Element) n).getAttribute("value"); + } + } + String name = element.getAttribute("name"); String typeStr = mapping.getTargetTypeOf(element.getAttribute("type")); @@ -215,7 +254,80 @@ private Buildable createBuildable(Element element) { } Type type = Type.valueOf(typeStr); - return new Buildable(id, name, type); + + Buildable temp = new Buildable(id, name, type); + + Buildable buildableForInheritence = null; + Buildable buildableForAttributes = null; + + if ("class".equals(element.getAttribute("type"))) { + + NodeList classNodeList = element.getElementsByTagName("property"); + for (int i = 0; i < classNodeList.getLength(); i++) { + Node n = classNodeList.item(i); + + Type childType = null; + Type attributueType = null; + + + for (Linking l : mapping.getLinkings()) { + if ("class".equals(l.getSource())) { + for (Binding b : l.getBindings()) { + if ("ChildClasses".equals(b.getFrom())) { + if ("tunnel".equals(b.getTo())) { + childType = Type.TUNNEL; + } else if ("bridge".equals(b.getTo())) { + childType = Type.BRIDGE; + } + } else if ("AttributeClasses".equals(b.getFrom())) { + if ("tunnel".equals(b.getTo())) { + attributueType = Type.TUNNEL; + } else if ("bridge".equals(b.getTo())) { + attributueType = Type.BRIDGE; + } + } + } + } + } + if (n instanceof Element && "ChildClasses".equals(((Element) n).getAttribute("name")) && !"".equals(((Element) n).getAttribute("value")) && childType != null) { + String children = ((Element) n).getAttribute("value"); + children = children.replaceAll("\\[", "").replaceAll("\\]", "" ); + List childrenList = Arrays.asList(children.split(", ")); + + for (String s : childrenList) { + buildableForInheritence = new Buildable ( + "zxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "Relation_based_on_inheritance", + childType, + new Point(0,0,0), + new Point(0,0,0) + ); + buildableForInheritence.addAttribute("target", s); + buildableForInheritence.addAttribute("torches", "6"); + temp.addChild(buildableForInheritence); + } + } else if (n instanceof Element && "AttributeClasses".equals(((Element)n).getAttribute("name")) && !"".equals(((Element) n).getAttribute("value")) && attributueType != null) { + String attributes = ((Element) n).getAttribute("value"); + attributes = attributes.replaceAll("\\[", "").replaceAll("\\]", "" ); + List attributeList = Arrays.asList(attributes.split(", ")); + for (String s : attributeList) { + buildableForAttributes = new Buildable ( + "yxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "Relation_based_on_attributes", + attributueType, + new Point(0,0,0), + new Point(0,0,0) + ); + buildableForAttributes.addAttribute("target", s); + buildableForAttributes.addAttribute("torches", "6"); + temp.addChild(buildableForAttributes); + } + + } + } + } + + return temp; } private Map createAttributeMap(Element element) { @@ -229,6 +341,7 @@ private Map createAttributeMap(Element element) { Element propElement = (Element) propNode; Object value; Double doubleValue = null; + // itt állítja be a valuenak a propertyk értékeit switch(propElement.getAttribute("type")) { case "string": value = propElement.getAttribute("value"); @@ -249,6 +362,7 @@ private Map createAttributeMap(Element element) { Element parentElement = (Element)element.getParentNode(); limitController.add(parentElement.getAttribute("type").toLowerCase(), propElement.getAttribute("name"), doubleValue); } + //itt szedi be a property nevét és a hozzá tartozó értéket String name = propElement.getAttribute("name"); attributes.put( name, @@ -269,11 +383,11 @@ private void prepareBuildables(BuildableTree buildables) { Iterator it = buildables.iterator(); while(it.hasNext()) { Buildable b = it.next(); - + //oké, az alap 9-ről mindig 3-mal nő a belső gyermekeknél a size és hozzá van adva + 1 if(b.getSizeX() % 2 == 0) b.setSizeX(b.getSizeX() + 1); if(b.getSizeY() % 2 == 0) b.setSizeY(b.getSizeY() + 1); if(b.getSizeZ() % 2 == 0) b.setSizeZ(b.getSizeZ() + 1); - + //és itt van, ha ez kisebb mint a minimum érték, akkor beállítja 9-re. if(b.getSizeX() < MIN_SIZE) b.setSizeX(MIN_SIZE); if(b.getSizeY() < MIN_SIZE) b.setSizeY(MIN_SIZE); if(b.getSizeZ() < MIN_SIZE) b.setSizeZ(MIN_SIZE); @@ -283,7 +397,7 @@ private void prepareBuildables(BuildableTree buildables) { } } } - + //sztem itt építi fel a fát public boolean validateBuildableStructure(BuildableTree buildableTree) throws NotValidBuildableStructure{ BuildableTree.Iterator iterator = buildableTree.iterator(); diff --git a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/conversions/Conversion.java b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/conversions/Conversion.java index 5d52d6ac..c22c89db 100644 --- a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/conversions/Conversion.java +++ b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/conversions/Conversion.java @@ -4,7 +4,7 @@ import java.util.Collections; import java.util.List; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import codemetropolis.toolchain.mapping.model.Limit; import codemetropolis.toolchain.mapping.model.Parameter; diff --git a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/conversions/ConversionAdapter.java b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/conversions/ConversionAdapter.java index 06a1692a..cb3c46d7 100644 --- a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/conversions/ConversionAdapter.java +++ b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/conversions/ConversionAdapter.java @@ -2,9 +2,9 @@ import java.util.List; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.adapters.XmlAdapter; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.adapters.XmlAdapter; import codemetropolis.toolchain.mapping.model.Parameter; diff --git a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/exceptions/MappingWriterException.java b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/exceptions/MappingWriterException.java index 408fe202..109ee8e8 100644 --- a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/exceptions/MappingWriterException.java +++ b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/exceptions/MappingWriterException.java @@ -24,4 +24,4 @@ public MappingWriterException(Throwable cause) { super(cause); } -} +} \ No newline at end of file diff --git a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Binding.java b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Binding.java index e57d9310..83d0baac 100644 --- a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Binding.java +++ b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Binding.java @@ -4,11 +4,11 @@ import java.util.Collections; import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; import codemetropolis.toolchain.mapping.conversions.Conversion; diff --git a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Constant.java b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Constant.java index b05a1409..f3aaf99a 100644 --- a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Constant.java +++ b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Constant.java @@ -1,8 +1,8 @@ package codemetropolis.toolchain.mapping.model; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; @XmlAccessorType(XmlAccessType.FIELD) public class Constant { diff --git a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Linking.java b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Linking.java index 2c28b50d..848a79ea 100644 --- a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Linking.java +++ b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Linking.java @@ -6,10 +6,10 @@ import java.util.List; import java.util.Map; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; import codemetropolis.toolchain.commons.cmxml.Buildable.Type; import codemetropolis.toolchain.commons.util.Resources; @@ -22,10 +22,10 @@ public class Linking { private static final Map SUPPORTED_PROPERTIES = new HashMap<>(); static { - SUPPORTED_PROPERTIES.put(Type.FLOOR, new String[]{"width", "height", "length", "character", "external_character", "torches"}); + SUPPORTED_PROPERTIES.put(Type.FLOOR, new String[]{"width","BuiltMetric1", "height","BuiltMetric2", "length","BuiltMetric3", "character", "external_character", "torches"}); SUPPORTED_PROPERTIES.put(Type.CELLAR, new String[]{"width", "height", "length", "character", "external_character", "torches"}); - SUPPORTED_PROPERTIES.put(Type.GARDEN, new String[]{"tree-ratio", "mushroom-ratio", "flower-ratio"}); - SUPPORTED_PROPERTIES.put(Type.GROUND, new String[]{}); + SUPPORTED_PROPERTIES.put(Type.GARDEN, new String[]{"tree-ratio", "mushroom-ratio", "flower-ratio", "tunnel", "bridge", "monster-count", "monster-label", "pig"}); + SUPPORTED_PROPERTIES.put(Type.GROUND, new String[]{"biome-id"}); } @XmlAttribute @@ -71,7 +71,6 @@ public void addBinding(Binding binding) { public void removeBinding(Binding binding) { bindings.remove(binding); } - public static String[] getSupportedProperties(Type buildableType) { return SUPPORTED_PROPERTIES.get(buildableType); } diff --git a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Mapping.java b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Mapping.java index 1aaac0fa..e23ed78a 100644 --- a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Mapping.java +++ b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Mapping.java @@ -8,16 +8,16 @@ import java.util.List; import java.util.Map; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import codemetropolis.toolchain.mapping.exceptions.MappingReaderException; import codemetropolis.toolchain.mapping.exceptions.MappingWriterException; diff --git a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Parameter.java b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Parameter.java index 3dbcd301..574bc3d0 100644 --- a/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Parameter.java +++ b/sources/toolchain/mapping/src/main/java/codemetropolis/toolchain/mapping/model/Parameter.java @@ -1,8 +1,8 @@ package codemetropolis.toolchain.mapping.model; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; @XmlAccessorType(XmlAccessType.FIELD) public class Parameter { diff --git a/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/MappingExecutorArgsTest.java b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/MappingExecutorArgsTest.java new file mode 100644 index 00000000..31b3df13 --- /dev/null +++ b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/MappingExecutorArgsTest.java @@ -0,0 +1,22 @@ +package codemetropolis.toolchain.mapping; + +import junit.framework.TestCase; + +public class MappingExecutorArgsTest extends TestCase { + + MappingExecutorArgs testObj; + + public void setup() { + testObj = null; + } + + public void testMappingExecutorArgs() { + testObj = new MappingExecutorArgs("testCDF", "testOutput", "testMapping", 1.0, true); + assertEquals("testCDF", testObj.getCdfFile()); + assertEquals("testOutput", testObj.getOutputFile()); + assertEquals("testMapping", testObj.getMappingFile()); + assertEquals(1.0, testObj.getScale()); + assertEquals(true, testObj.isHierarchyValidationEnabled()); + } + +} diff --git a/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/control/LimitControllerTest.java b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/control/LimitControllerTest.java new file mode 100644 index 00000000..ac6564f1 --- /dev/null +++ b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/control/LimitControllerTest.java @@ -0,0 +1,22 @@ +package codemetropolis.toolchain.mapping.control; + +import junit.framework.TestCase; + +public class LimitControllerTest extends TestCase { + + LimitController testObj; + + public void setup() { + testObj = null; + } + + public void testAdd() { + testObj = new LimitController(); + + testObj.add("name", "from", 2.0); + + assertNotNull(testObj.getLimit("name", "from")); + assertEquals(1, testObj.getLimit("name", "from").getValueSetSize()); + } + +} \ No newline at end of file diff --git a/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/control/MappingControllerTest.java b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/control/MappingControllerTest.java new file mode 100644 index 00000000..fd8f49b6 --- /dev/null +++ b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/control/MappingControllerTest.java @@ -0,0 +1,69 @@ +package codemetropolis.toolchain.mapping.control; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; + +import codemetropolis.toolchain.commons.cmxml.Buildable; +import codemetropolis.toolchain.commons.cmxml.Buildable.Type; +import codemetropolis.toolchain.mapping.model.Mapping; +import junit.framework.TestCase; + +public class MappingControllerTest extends TestCase { + + MappingController testObj; + + public void setup() { + testObj = null; + } + + public void testSetProperty() { + + testObj = new MappingController(new Mapping()); + + Buildable b = new Buildable("id", "name", Type.GARDEN); + b.setSizeX(0); + b.setSizeY(0); + + try { + Method method = testObj.getClass().getDeclaredMethod("setProperty", Buildable.class, String.class, Object.class, boolean.class); + method.setAccessible(true); + + method.invoke(testObj, b, "width", 3.0, false); + + assertEquals(3, b.getSizeX()); + + method.invoke(testObj, b, "height", 5.0, false); + + assertEquals(5, b.getSizeY()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void testFindRoot() { + + testObj = new MappingController(new Mapping()); + + Collection buildables = new ArrayList<>(); + + Buildable b = new Buildable("id", "name", Type.GARDEN); + + buildables.add(b); + + try { + Method method = testObj.getClass().getDeclaredMethod("findRoot", Collection.class); + method.setAccessible(true); + + if (b.isRoot()) { + assertEquals(b, method.invoke(testObj, buildables)); + } else { + assertNull(method.invoke(testObj, buildables)); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } + +} \ No newline at end of file diff --git a/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/conversions/NormalizeConversionTest.java b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/conversions/NormalizeConversionTest.java new file mode 100644 index 00000000..7d198124 --- /dev/null +++ b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/conversions/NormalizeConversionTest.java @@ -0,0 +1,28 @@ +package codemetropolis.toolchain.mapping.conversions; + +import codemetropolis.toolchain.mapping.model.Limit; +import junit.framework.TestCase; + +public class NormalizeConversionTest extends TestCase { + + NormalizeConversion testObj; + + public void setup() { + testObj = null; + } + + public void testApply() { + testObj = new NormalizeConversion(); + + Limit l1 = new Limit(); + l1.add(42); + + Limit l2 = new Limit(); + l2.add(41); + l2.add(43); + + assertEquals(1.0, testObj.apply(24.0, l1)); + assertEquals(0.5, testObj.apply(42.0, l2)); + } + +} diff --git a/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/conversions/ToDoubleConversionTest.java b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/conversions/ToDoubleConversionTest.java new file mode 100644 index 00000000..46d8fb89 --- /dev/null +++ b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/conversions/ToDoubleConversionTest.java @@ -0,0 +1,21 @@ +package codemetropolis.toolchain.mapping.conversions; + +import codemetropolis.toolchain.mapping.model.Limit; +import junit.framework.TestCase; + +public class ToDoubleConversionTest extends TestCase { + + ToDoubleConversion testObj; + + public void setup() { + testObj = null; + } + + public void testApply() { + testObj = new ToDoubleConversion(); + + assertEquals(2.0, testObj.apply(2.0, new Limit())); + assertEquals(2.0, testObj.apply("2.0", new Limit())); + } + +} \ No newline at end of file diff --git a/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/conversions/ToIntConversionTest.java b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/conversions/ToIntConversionTest.java new file mode 100644 index 00000000..f8599cb8 --- /dev/null +++ b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/conversions/ToIntConversionTest.java @@ -0,0 +1,21 @@ +package codemetropolis.toolchain.mapping.conversions; + +import codemetropolis.toolchain.mapping.model.Limit; +import junit.framework.TestCase; + +public class ToIntConversionTest extends TestCase { + + ToIntConversion testObj; + + public void setup() { + testObj = null; + } + + public void testApply() { + testObj = new ToIntConversion(); + + assertEquals(3, testObj.apply(3.21, new Limit())); + assertEquals(4, testObj.apply("4", new Limit())); + } + +} \ No newline at end of file diff --git a/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/BindingTest_2.java b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/BindingTest_2.java new file mode 100644 index 00000000..e1fe4fbc --- /dev/null +++ b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/BindingTest_2.java @@ -0,0 +1,24 @@ +package codemetropolis.toolchain.mapping.model; + +import static org.junit.Assert.*; + +import org.junit.Test; + +/** + * Test class for {@link Binding}. + * + * @author Gecs Bernat {@literal } + */ + +public class BindingTest_2 { + + String from = "valami.xml"; + String to = "csv"; + + @Test + public final void testGetVariableId() { + Binding binding = new Binding(from,to); + assertNull(binding.getVariableId()); + } + +} \ No newline at end of file diff --git a/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/LimitTest.java b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/LimitTest.java new file mode 100644 index 00000000..eddea6a6 --- /dev/null +++ b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/LimitTest.java @@ -0,0 +1,22 @@ +package codemetropolis.toolchain.mapping.model; + +import junit.framework.TestCase; + +public class LimitTest extends TestCase { + + Limit testObj; + + public void setup() { + testObj = null; + } + + public void testAdd() { + testObj = new Limit(); + + testObj.add(3.0); + assertEquals(1, testObj.getValueSetSize()); + assertEquals(3.0, testObj.getMax()); + assertEquals(3.0, testObj.getMin()); + } + +} \ No newline at end of file diff --git a/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/LimitTest2.java b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/LimitTest2.java new file mode 100644 index 00000000..a2bc2bc5 --- /dev/null +++ b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/LimitTest2.java @@ -0,0 +1,170 @@ +package codemetropolis.toolchain.mapping.model; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test class for {@link Limit}. Testing if after using {@code add} functions getter methods will work properly. + * + * @author Abigel Mester {@literal } + */ +public class LimitTest2 { + + private static final double DELTA = 1e-15; + + /** + * Check if size is correct when no values are added. + */ + @Test + public void testGetValueTestSizeDefault() { + Limit limit = new Limit(); + Assert.assertEquals(limit.getValueSetSize(), 0); + } + + /** + * Check if size is correct when one positive value is added. + */ + @Test + public void testGetValueTestSizeOne() { + Limit limit = new Limit(); + limit.add(5); + Assert.assertEquals(limit.getValueSetSize(), 1); + } + + /** + * Check if size is correct when one negative value is added. + */ + @Test + public void testGetValueTestSizeOneNegative() { + Limit limit = new Limit(); + limit.add(-63234.2); + Assert.assertEquals(limit.getValueSetSize(), 1); + } + + /** + * Check if size is correct when two values are added. + */ + @Test + public void testGetValueTestSizeTwo() { + Limit limit = new Limit(); + limit.add(5342); + limit.add(-6.2); + Assert.assertEquals(limit.getValueSetSize(), 2); + } + + /** + * Check if size is correct when more values are added. + */ + @Test + public void testGetValueTestSizeMore() { + Limit limit = new Limit(); + for(int i = -9; i < 30; i++) { + limit.add(i); + } + Assert.assertEquals(limit.getValueSetSize(), 39); + } + + /** + * Check if max value is correct when no values are added. + */ + @Test + public void testGetMaxDefault() { + Limit limit = new Limit(); + Assert.assertEquals(limit.getMax(), Double.NEGATIVE_INFINITY, DELTA); + } + + /** + * Check if max value is correct when one positive value is added. + */ + @Test + public void testGetMaxOne() { + Limit limit = new Limit(); + limit.add(5); + Assert.assertEquals(limit.getMax(), 5, DELTA); + } + + /** + * Check if max value is correct when one negative value is added. + */ + @Test + public void testGetMaxOneNegative() { + Limit limit = new Limit(); + limit.add(-63234.2); + Assert.assertEquals(limit.getMax(), -63234.2, DELTA); + } + + /** + * Check if max value is correct when two values are added. + */ + @Test + public void testGetMaxTwo() { + Limit limit = new Limit(); + limit.add(5342); + limit.add(-6.2); + Assert.assertEquals(limit.getMax(), 5342, DELTA); + } + + /** + * Check if max value is correct when more values are added. + */ + @Test + public void testGetMaxMore() { + Limit limit = new Limit(); + for(int i = -9; i < 30; i++) { + limit.add(i); + } + Assert.assertEquals(limit.getMax(), 29, DELTA); + } + + /** + * Check if min value is correct when no values are added. + */ + @Test + public void testGetMinDefault() { + Limit limit = new Limit(); + Assert.assertEquals(limit.getMin(), Double.POSITIVE_INFINITY, DELTA); + } + + /** + * Check if min value is correct when one positive value is added. + */ + @Test + public void testGetMinOne() { + Limit limit = new Limit(); + limit.add(5); + Assert.assertEquals(limit.getMin(), 5, DELTA); + } + + /** + * Check if min value is correct when one negative value is added. + */ + @Test + public void testGetMinOneNegative() { + Limit limit = new Limit(); + limit.add(-63234.2); + Assert.assertEquals(limit.getMin(), -63234.2, DELTA); + } + + /** + * Check if min value is correct when two values are added. + */ + @Test + public void testGetMinTwo() { + Limit limit = new Limit(); + limit.add(5342); + limit.add(-6.2); + Assert.assertEquals(limit.getMin(), -6.2, DELTA); + } + + /** + * Check if min value is correct when more values are added. + */ + @Test + public void testGetMinMore() { + Limit limit = new Limit(); + for(int i = -9; i < 30; i++) { + limit.add(i); + } + Assert.assertEquals(limit.getMin(), -9, DELTA); + } +} \ No newline at end of file diff --git a/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/ParameterTest.java b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/ParameterTest.java new file mode 100644 index 00000000..25556e0f --- /dev/null +++ b/sources/toolchain/mapping/src/test/java/codemetropolis/toolchain/mapping/model/ParameterTest.java @@ -0,0 +1,41 @@ +package codemetropolis.toolchain.mapping.model; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test class for {@link Parameter}. + * + * @author Gecs Bernat {@literal } + */ + +public class ParameterTest { + + String parameter1 = "param1"; + String parameter2 = "param2"; + + @Test + public final void testGetName() { + Parameter parameter = new Parameter(parameter1,parameter2); + Assert.assertEquals(parameter.getName(), parameter1); + } + + @Test + public final void testSetName() { + Parameter parameter = new Parameter(parameter1,parameter2); + Assert.assertEquals(parameter.getName(), parameter1); + } + + @Test + public final void testGetValue() { + Parameter parameter = new Parameter(parameter1,parameter2); + Assert.assertEquals(parameter.getValue(), parameter2); + } + + @Test + public final void testSetValue() { + Parameter parameter = new Parameter(parameter1,parameter2); + Assert.assertEquals(parameter.getValue(), parameter2); + } + +} \ No newline at end of file diff --git a/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/conversions/MultiplyConversionTest.java b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/conversions/MultiplyConversionTest.java new file mode 100644 index 00000000..3719bbe5 --- /dev/null +++ b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/conversions/MultiplyConversionTest.java @@ -0,0 +1,50 @@ +package codemetropolis.toolchain.mapping.conversions; + +import java.util.List; +import static org.junit.Assert.assertTrue; +import org.junit.BeforeClass; +import org.junit.Test; +import codemetropolis.toolchain.mapping.model.Limit; +import codemetropolis.toolchain.mapping.model.Parameter; + +public class MultiplyConversionTest { + + public static Conversion conversion; + + @BeforeClass + public static void setUpBeforeClass() { + + conversion = new MultiplyConversion(); + + conversion.addParameters(new Parameter("name1", "1.5"), new Parameter("name2", "2"), new Parameter("name3", "3.4")); + } + + @Test + public void testGetParameters() { + boolean test = false; + List parameterList = conversion.getParameters(); + + for (Parameter p : parameterList) { + if ("name1".equals(p.getName())) { + test = true; + } + } + + assertTrue(test); + + } + + @Test + public void testClearParameters() { + conversion.clearParameters(); + assertTrue(conversion.getParameters().isEmpty()); + } + + + @Test + public void testApply() { + double val = (double)conversion.apply("0.2", new Limit()); + + assertTrue(0.2 == val); + } +} \ No newline at end of file diff --git a/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/conversions/QuantizationConversionTest.java b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/conversions/QuantizationConversionTest.java new file mode 100644 index 00000000..30bf3a10 --- /dev/null +++ b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/conversions/QuantizationConversionTest.java @@ -0,0 +1,34 @@ +package codemetropolis.toolchain.mapping.conversions; + +import static org.junit.Assert.assertEquals; + +import codemetropolis.toolchain.mapping.model.Limit; +import codemetropolis.toolchain.mapping.model.Parameter; + +import org.junit.Test; +import org.junit.Before; + +public class QuantizationConversionTest { + + public Conversion conversion; + + @Before + public void setUp() throws Exception { + conversion = new QuantizationConversion(); + conversion.addParameter(new Parameter("level0", "1")); + conversion.addParameter(new Parameter("level1", "2")); + conversion.addParameter(new Parameter("level2", "4")); + } + + @Test + public void testApply() { + Limit limit = new Limit(); + limit.add(50); + limit.add(0); + limit.add(100); + double valueToConvert = 54; + String actual = (String) conversion.apply(valueToConvert, limit); + assertEquals("2", actual); + } + +} diff --git a/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/conversions/TestSwitchConversion.java b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/conversions/TestSwitchConversion.java new file mode 100644 index 00000000..ebacc93b --- /dev/null +++ b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/conversions/TestSwitchConversion.java @@ -0,0 +1,54 @@ +package codemetropolis.toolchain.mapping.conversions; + +import java.util.List; +import static org.junit.Assert.assertTrue; +import org.junit.BeforeClass; +import org.junit.Test; +import codemetropolis.toolchain.mapping.model.Limit; +import codemetropolis.toolchain.mapping.model.Parameter; + +public class TestSwitchConversion { + + public static Conversion conversion; + + @BeforeClass + public static void setUpBeforeClass() { + + conversion = new SwitchConversion(); + + conversion.addParameters(new Parameter("default", "1.5"), new Parameter("name2", "2"), new Parameter("name3", "3.4")); + } + + @Test + public void testGetParametersValue() { + boolean test = false; + List parameterList = conversion.getParameters(); + + for (Parameter p : parameterList) { + if ("1.5".equals(p.getValue())) { + test = true; + } + } + + assertTrue(test); + + } + + @Test + public void testClearParametersContains() { + conversion.clearParameters(); + + Parameter param = new Parameter("TEST", "123"); + + conversion.addParameter(param); + + assertTrue(conversion.getParameters().contains(param)); + } + + @Test + public void testApply() { + String val = (String)conversion.apply("0.2", new Limit()); + + assertTrue("1.5".equals(val)); + } +} diff --git a/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/model/LinkingTest.java b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/model/LinkingTest.java new file mode 100644 index 00000000..f8035fa7 --- /dev/null +++ b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/model/LinkingTest.java @@ -0,0 +1,67 @@ +package codemetropolis.toolchain.mapping.model; + +import java.io.FileNotFoundException; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import codemetropolis.toolchain.mapping.exceptions.MappingReaderException; +import codemetropolis.toolchain.mapping.exceptions.MissingResourceException; +import codemetropolis.toolchain.mapping.exceptions.NotSupportedLinkingException; + +/** + * Test cases for the {@link Linking} class. + * @author Viktor Meszaros {@literal } + * + */ +public class LinkingTest { + + public static String TEST_FILE_LOCATION = "./test/sourcemeter_mapping_example_2_0.xml"; + + @Test + public void testValidateShouldNotThrowException() throws MappingReaderException, FileNotFoundException{ + + boolean exceptionThrown = false; + + Mapping mapping = Mapping.readFromXML(TEST_FILE_LOCATION); + + Linking linking = mapping.getLinkings().get(0); + List resources = mapping.getResources(); + + try { + linking.validate(resources); + } catch (NotSupportedLinkingException e) { + exceptionThrown = true; + } catch (MissingResourceException e) { + exceptionThrown = true; + } + + Assert.assertFalse(exceptionThrown); + } + + @Test + public void testValidateShouldThrowException() throws MappingReaderException, FileNotFoundException{ + + boolean exceptionThrown = false; + + String badTarget = "skyscraper"; + + Mapping mapping = Mapping.readFromXML(TEST_FILE_LOCATION); + + Linking linking = mapping.getLinkings().get(0); + linking.setTarget(badTarget); + List resources = mapping.getResources(); + + try { + linking.validate(resources); + } catch (NotSupportedLinkingException e) { + exceptionThrown = true; + } catch (MissingResourceException e) { + exceptionThrown = true; + } + + Assert.assertTrue(exceptionThrown); + } + +} diff --git a/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/model/MappingControllerTest.java b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/model/MappingControllerTest.java new file mode 100644 index 00000000..10c2eed2 --- /dev/null +++ b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/model/MappingControllerTest.java @@ -0,0 +1,39 @@ +package codemetropolis.toolchain.mapping.model; + +import java.io.FileNotFoundException; + +import org.junit.Assert; +import org.junit.Test; + +import codemetropolis.toolchain.commons.cdf.exceptions.CdfReaderException; +import codemetropolis.toolchain.mapping.control.MappingController; +import codemetropolis.toolchain.mapping.exceptions.MappingReaderException; + +/** + * Test cases for the {@link MappingController} class. + * @author Viktor Meszaros {@literal } + * + */ +public class MappingControllerTest { + + public static String MAPPING_FILE_LOCATION = "./test/sourcemeter_mapping_example_2_0.xml"; + public static String TEST_FILE_LOCATION = "./test/output_test.xml"; + + + @Test + public void testCreateBuildablesFromCdfShouldNotThrowException() throws FileNotFoundException, MappingReaderException{ + Mapping mapping = Mapping.readFromXML(MAPPING_FILE_LOCATION); + + MappingController mController = new MappingController(mapping); + boolean exceptionThrown = false; + + try { + mController.createBuildablesFromCdf(TEST_FILE_LOCATION); + } catch (CdfReaderException e) { + exceptionThrown = true; + } + + Assert.assertFalse(exceptionThrown); + } + +} diff --git a/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/model/MappingTest.java b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/model/MappingTest.java new file mode 100644 index 00000000..43f3105f --- /dev/null +++ b/sources/toolchain/mapping/test/codemetropolis/toolchain/mapping/model/MappingTest.java @@ -0,0 +1,34 @@ +package codemetropolis.toolchain.mapping.model; + +import java.io.FileNotFoundException; + +import org.junit.Assert; +import org.junit.Test; + +import codemetropolis.toolchain.mapping.exceptions.MappingReaderException; + +/** + * Test cases for the {@link Mapping} class. + * @author Viktor Meszaros {@literal } + * + */ +public class MappingTest { + + public static String TEST_FILE_LOCATION = "./test/sourcemeter_mapping_example_2_0.xml"; + + @Test + public void testReadFromXMLShouldNotThrowException() { + + boolean exceptionThrown = false; + + try { + Mapping.readFromXML(TEST_FILE_LOCATION); + }catch (MappingReaderException e) { + exceptionThrown = true; + } catch (FileNotFoundException e) { + exceptionThrown = true; + } + + Assert.assertFalse(exceptionThrown); + } +} diff --git a/sources/toolchain/mapping/test/output_test.xml b/sources/toolchain/mapping/test/output_test.xml new file mode 100644 index 00000000..560020c9 --- /dev/null +++ b/sources/toolchain/mapping/test/output_test.xml @@ -0,0 +1,13180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/mapping/sourcemeter_mapping_example_2_0.xml b/sources/toolchain/mapping/test/sourcemeter_mapping_example_2_0.xml similarity index 100% rename from examples/mapping/sourcemeter_mapping_example_2_0.xml rename to sources/toolchain/mapping/test/sourcemeter_mapping_example_2_0.xml diff --git a/sources/toolchain/placing/.project b/sources/toolchain/placing/.project index 3f758d7f..36d56839 100644 --- a/sources/toolchain/placing/.project +++ b/sources/toolchain/placing/.project @@ -1,23 +1,20 @@ - codemetropolis-toolchain-placing - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - + codemetropolis-toolchain-placing + NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. + + codemetropolis-toolchain-commons + + + + org.eclipse.jdt.core.javabuilder + + + org.eclipse.m2e.core.maven2Builder + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + diff --git a/sources/toolchain/placing/placingToRendering.xml b/sources/toolchain/placing/placingToRendering.xml deleted file mode 100644 index 2870b290..00000000 --- a/sources/toolchain/placing/placingToRendering.xml +++ /dev/null @@ -1,2206 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sources/toolchain/placing/pom.xml b/sources/toolchain/placing/pom.xml index c57826ce..e4ad14df 100644 --- a/sources/toolchain/placing/pom.xml +++ b/sources/toolchain/placing/pom.xml @@ -36,12 +36,21 @@ ${project.groupId} commons + 1.4.0 + + + ${project.groupId} + converter + 1.4.0 - args4j args4j 2.32 + + junit + junit + \ No newline at end of file diff --git a/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/CityMapGUI.java b/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/CityMapGUI.java index f3a7fed7..5fcad078 100644 --- a/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/CityMapGUI.java +++ b/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/CityMapGUI.java @@ -90,6 +90,12 @@ public void paint(Graphics g) { case CELLAR : g2d.setColor(new Color(230, 50, 40)); //red break; + case TUNNEL : + g2d.setColor(new Color(122, 122, 122)); //grey + break; + case BRIDGE : + g2d.setColor(new Color(164, 66, 244)); //purple + break; default: break; } diff --git a/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/BuildableWrapper.java b/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/BuildableWrapper.java index 462015e1..cd28ee1b 100644 --- a/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/BuildableWrapper.java +++ b/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/BuildableWrapper.java @@ -68,7 +68,7 @@ public List getChildren(Map> houses) { for(Buildable c : ((Buildable)buildable).getChildren()) { if(c.getType() == Buildable.Type.FLOOR || c.getType() == Buildable.Type.CELLAR) continue; result.add(new BuildableWrapper(c)); - } + } if(houses.get((Buildable)buildable) != null) { for(House h : houses.get((Buildable)buildable)) { result.add(new BuildableWrapper(h)); diff --git a/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/House.java b/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/House.java index 11481ba4..2b76dbf8 100644 --- a/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/House.java +++ b/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/House.java @@ -18,7 +18,7 @@ public class House { private Buildable bottomFloor; private Buildable topCellar; private Buildable bottomCellar; - + public House(int minHeight, int maxHeight) { this.minHeight = minHeight; this.maxHeight = maxHeight; @@ -151,5 +151,5 @@ public void setPositionZR(int z) { public Buildable getParent() { return parent; } - + } diff --git a/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/PackLayout.java b/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/PackLayout.java index 3983d2bd..6b61ca8b 100644 --- a/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/PackLayout.java +++ b/sources/toolchain/placing/src/main/java/codemetropolis/toolchain/placing/layout/pack/PackLayout.java @@ -6,7 +6,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; +import codemetropolis.toolchain.commons.cmxml.Attribute; import codemetropolis.toolchain.commons.cmxml.Buildable; import codemetropolis.toolchain.commons.cmxml.BuildableTree; import codemetropolis.toolchain.commons.cmxml.Point; @@ -16,7 +18,9 @@ import codemetropolis.toolchain.placing.layout.pack.RectanglePacker.Rectangle; public class PackLayout extends Layout { - + public static final int LINKING_WIDTH = 2; + public static final String LINKING_ATTRIBUTE_TARGET = "target"; + private final int SPACE = 3; @Override @@ -25,6 +29,220 @@ public void apply(BuildableTree buildables) throws LayoutException { Map> houses = createHouses(buildables); BuildableWrapper root = new BuildableWrapper(buildables.getRoot()); packRecursive(root, houses); + + makeLinkings(buildables); + } + + private void makeLinkings(BuildableTree buildables) { + + List extendedBuildables = new ArrayList(); + + for(Buildable b : buildables.getBuildables()) { + + if (b.getType() != Buildable.Type.TUNNEL && b.getType() != Buildable.Type.BRIDGE) { + continue; + } + + Buildable parent = b.getParent(); + String id = b.getAttributeValue(LINKING_ATTRIBUTE_TARGET); + + if (id == null) { + buildables.getBuildables().remove(b); + b.addAttribute(new Attribute("standalone", "")); + b.addAttribute(new Attribute("orientation", "")); + continue; + } + + Buildable target = buildables.getBuildable(id); + + if (target == null) { + buildables.getBuildables().remove(b); + b.addAttribute(new Attribute("standalone", "")); + b.addAttribute(new Attribute("orientation", "")); + continue; + } + + if(target.getId() == parent.getId()) { + buildables.getBuildables().remove(b); + } + + Point parentCenter = new Point(parent.getPositionX() + parent.getSizeX()/2, 0, parent.getPositionZ() + parent.getSizeZ()/2); + Point targetCenter = new Point(target.getPositionX() + target.getSizeX()/2, 0, target.getPositionZ() + target.getSizeZ()/2); + + if (parentCenter.getX() == targetCenter.getX()) { + + b.setPositionX(parentCenter.getX() - LINKING_WIDTH/2); + b.setSizeX(LINKING_WIDTH); + + int distance = targetCenter.getZ() - parentCenter.getZ(); + + if (parentCenter.getZ() < targetCenter.getZ()) { + // P - parent, T - target, X - undefined + // Position: + // X X X + // X P X + // X T X + // X X X + + b.setPositionZ(parentCenter.getZ()); + b.setSizeZ(distance); + + b.addAttribute(new Attribute("standalone", "true")); + b.addAttribute(new Attribute("orientation", "SOUTH")); + + } else { + // Position: + // X X X + // X T X + // X P X + // X X X + + b.setPositionZ(targetCenter.getZ()); + b.setSizeZ(-distance); + + b.addAttribute(new Attribute("standalone", "true")); + b.addAttribute(new Attribute("orientation", "NORTH")); + + } + } else if (parentCenter.getZ() == targetCenter.getZ()) { + + b.setPositionZ(parentCenter.getZ() - LINKING_WIDTH/2); + b.setSizeZ(LINKING_WIDTH); + + int distance = targetCenter.getX() - parentCenter.getX(); + + if (parent.getPositionX() < target.getPositionX()) { + // Position: + // X X X X + // X P T X + // X X X X + + b.setPositionX(parentCenter.getX()); + b.setSizeX(distance); + + b.addAttribute(new Attribute("standalone", "true")); + b.addAttribute(new Attribute("orientation", "EAST")); + + } else { + // Position: + // X X X X + // X T P X + // X X X X + + b.setPositionX(targetCenter.getX()); + b.setSizeX(-distance); + + b.addAttribute(new Attribute("standalone", "true")); + b.addAttribute(new Attribute("orientation", "WEST")); + + } + } else if (parentCenter.getX() > targetCenter.getX()) { + + b.setPositionZ(parentCenter.getZ() - LINKING_WIDTH/2); + b.setSizeZ(LINKING_WIDTH); + + b.setPositionX(targetCenter.getX() - LINKING_WIDTH/2); + b.setSizeX(parentCenter.getX() - targetCenter.getX() + LINKING_WIDTH); + + b.addAttribute(new Attribute("standalone", "false")); + b.addAttribute(new Attribute("orientation", "WEST")); + + Buildable new_b; + if (b.getType() == Buildable.Type.TUNNEL) { + new_b = new Buildable(UUID.randomUUID().toString(), "", Buildable.Type.TUNNEL); + } else { + new_b = new Buildable(UUID.randomUUID().toString(), "", Buildable.Type.BRIDGE); + } + + new_b.setPositionX(targetCenter.getX() - LINKING_WIDTH/2); + new_b.setSizeX(LINKING_WIDTH); + + int distance = parentCenter.getZ() - targetCenter.getZ(); + + if(parentCenter.getZ() > targetCenter.getZ()) { + // Position: + // X X X X + // X T X X + // X X P X + // X X X X + + new_b.setPositionZ(targetCenter.getZ()); + new_b.setSizeZ(distance + LINKING_WIDTH/2); + new_b.addAttribute(new Attribute("orientation", "SOUTH")); + + } else { + // Position: + // X X X X + // X X P X + // X T X X + // X X X X + + new_b.setPositionZ(parentCenter.getZ() - LINKING_WIDTH/2); + new_b.setSizeZ(-distance + LINKING_WIDTH/2); + new_b.addAttribute(new Attribute("orientation", "NORTH")); + + } + + new_b.addAttribute(new Attribute("standalone", "false")); + + extendedBuildables.add(new_b); + + target.addChild(new_b); + + } else { + b.setPositionZ(parentCenter.getZ() - LINKING_WIDTH/2); + b.setSizeZ(LINKING_WIDTH); + + b.setPositionX(parentCenter.getX() - LINKING_WIDTH/2); + b.setSizeX(targetCenter.getX() - parentCenter.getX() + LINKING_WIDTH); + + b.addAttribute(new Attribute("standalone", "false")); + b.addAttribute(new Attribute("orientation", "EAST")); + + Buildable new_b; + if (b.getType() == Buildable.Type.TUNNEL) { + new_b = new Buildable(UUID.randomUUID().toString(), "", Buildable.Type.TUNNEL); + } else { + new_b = new Buildable(UUID.randomUUID().toString(), "", Buildable.Type.BRIDGE); + } + + new_b.setPositionX(targetCenter.getX() - LINKING_WIDTH/2); + new_b.setSizeX(LINKING_WIDTH); + + int distance = targetCenter.getZ() - parentCenter.getZ(); + + if (parentCenter.getZ() > targetCenter.getZ()) { + // Position: + // X X X X + // X X T X + // X P X X + // X X X X + + new_b.setPositionZ(targetCenter.getZ()); + new_b.setSizeZ(-distance + LINKING_WIDTH/2); + new_b.addAttribute(new Attribute("orientation", "SOUTH")); + + } else { + // Position: + // X X X X + // X P X X + // X X T X + // X X X X + + new_b.setPositionZ(parentCenter.getZ() - LINKING_WIDTH/2); + new_b.setSizeZ(distance + LINKING_WIDTH/2); + new_b.addAttribute(new Attribute("orientation", "NORTH")); + + } + + new_b.addAttribute(new Attribute("standalone", "false")); + + extendedBuildables.add(new_b); + + target.addChild(new_b); + } + } + buildables.getBuildables().addAll(extendedBuildables); } private void prepareBuildables(BuildableTree buildables) { @@ -46,7 +264,16 @@ private Point getMaxSizes(Collection buildables) { } public void packRecursive(BuildableWrapper root, Map> houses) { - List children = root.getChildren(houses); + List tempChildren = root.getChildren(houses); + List children = new ArrayList(); + + for(BuildableWrapper c : tempChildren) { + if (c.buildable instanceof Buildable && (((Buildable)c.buildable).getType() == Buildable.Type.TUNNEL || ((Buildable)c.buildable).getType() == Buildable.Type.BRIDGE)) { + continue; + } + children.add(c); + } + for(BuildableWrapper c : children) { if(!c.getChildren(houses).isEmpty()) { packRecursive(c, houses); @@ -151,6 +378,8 @@ private Map> createHouses(BuildableTree buildables) throw housesOfParent.add(h); } } + return houses; } + } diff --git a/sources/toolchain/placing/src/test/java/codemetropolis/toolchain/placing/layout/LayoutTest.java b/sources/toolchain/placing/src/test/java/codemetropolis/toolchain/placing/layout/LayoutTest.java new file mode 100644 index 00000000..aa71d14d --- /dev/null +++ b/sources/toolchain/placing/src/test/java/codemetropolis/toolchain/placing/layout/LayoutTest.java @@ -0,0 +1,25 @@ +package codemetropolis.toolchain.placing.layout; + +import codemetropolis.toolchain.placing.exceptions.NonExistentLayoutException; +import codemetropolis.toolchain.placing.layout.pack.PackLayout; +import junit.framework.TestCase; + +public class LayoutTest extends TestCase { + + public void testParse() { + + try { + assert(Layout.parse("PACK") instanceof PackLayout); + } catch (NonExistentLayoutException e) { + fail(); + } + + try { + Layout.parse("WRONGTYPE"); + fail(); + } catch (NonExistentLayoutException e) {} + + + } + +} diff --git a/sources/toolchain/placing/src/test/java/codemetropolis/toolchain/placing/layout/pack/PackLayoutTest.java b/sources/toolchain/placing/src/test/java/codemetropolis/toolchain/placing/layout/pack/PackLayoutTest.java new file mode 100644 index 00000000..98349c8a --- /dev/null +++ b/sources/toolchain/placing/src/test/java/codemetropolis/toolchain/placing/layout/pack/PackLayoutTest.java @@ -0,0 +1,76 @@ +package codemetropolis.toolchain.placing.layout.pack; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; + +import codemetropolis.toolchain.commons.cmxml.Buildable; +import codemetropolis.toolchain.commons.cmxml.Buildable.Type; +import codemetropolis.toolchain.commons.cmxml.Point; +import junit.framework.TestCase; + +public class PackLayoutTest extends TestCase { + + PackLayout testObj; + + public void setup() { + testObj = null; + } + + public void testGetMaxSizes() { + + testObj = new PackLayout(); + + Buildable b = new Buildable("id", "name", Type.FLOOR, new Point(), new Point(10,10,10)); + BuildableWrapper w = new BuildableWrapper(b); + + Collection list = new ArrayList<>(); + + try { + Method method = testObj.getClass().getDeclaredMethod("getMaxSizes", Collection.class); + method.setAccessible(true); + + Point result = (Point) method.invoke(testObj, list); + assertEquals(0, result.getX()); + assertEquals(0, result.getY()); + assertEquals(0, result.getZ()); + + list.add(w); + result = (Point) method.invoke(testObj, list); + + assertEquals(10, result.getX()); + assertEquals(0, result.getY()); + assertEquals(10, result.getZ()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void testCalculateParentSize() { + + testObj = new PackLayout(); + + Buildable b = new Buildable("id", "name", Type.FLOOR, new Point(1,1,1), new Point(10,5,2)); + BuildableWrapper w = new BuildableWrapper(b); + + Collection list = new ArrayList<>(); + list.add(w); + + //space: 2 + //minX: 1, maxX: 1+10, minZ: 1, maxZ: 1+2 + //return: x: 11-1+4, z: 3-1+4 + try { + Method method = testObj.getClass().getDeclaredMethod("calculateParentSize", Collection.class, int.class); + method.setAccessible(true); + + Point result = (Point) method.invoke(testObj, list, 2); + assertEquals(14, result.getX()); + assertEquals(0, result.getY()); + assertEquals(6, result.getZ()); + } catch(Exception e) { + e.printStackTrace(); + } + + } + +} diff --git a/sources/toolchain/rendering/pom.xml b/sources/toolchain/rendering/pom.xml index b49d45d4..397dd544 100644 --- a/sources/toolchain/rendering/pom.xml +++ b/sources/toolchain/rendering/pom.xml @@ -28,6 +28,11 @@ org.apache.maven.plugins maven-dependency-plugin + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + @@ -48,15 +53,17 @@ graphlib 1.0 - - codemetropolis - cmblockmodifier - 1.0.1 - + org.apache.commons commons-lang3 3.4 + + + junit + junit + test + \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/CommandLineOptions.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/CommandLineOptions.java index 42f67dd5..6fe2d394 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/CommandLineOptions.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/CommandLineOptions.java @@ -15,7 +15,7 @@ public class CommandLineOptions { @Option(name="-s", aliases = { "-ow", "--overwrite", "--silent" }) private boolean overwriteSilently = false; - + public boolean showHelp() { return showHelp; } @@ -31,5 +31,4 @@ public String getWorld() { public boolean overwriteSilently() { return overwriteSilently; } - } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/Main.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/Main.java index 2de98730..0f75c0a3 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/Main.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/Main.java @@ -74,8 +74,8 @@ private void printProgress(String message, ProgressEvent event) { new RenderingExecutorArgs( options.getInputFile(), options.getWorld(), - options.overwriteSilently()) - ); + options.overwriteSilently() + )); } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/RenderingExecutor.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/RenderingExecutor.java index fad5b7de..d18a22b9 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/RenderingExecutor.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/RenderingExecutor.java @@ -15,45 +15,26 @@ import codemetropolis.toolchain.commons.util.Resources; import codemetropolis.toolchain.rendering.control.WorldBuilder; import codemetropolis.toolchain.rendering.events.ProgressEventListener; -import codemetropolis.toolchain.rendering.exceptions.BuildingTypeMismatchException; import codemetropolis.toolchain.rendering.exceptions.RenderingException; import codemetropolis.toolchain.rendering.exceptions.TooLongRenderDurationException; public class RenderingExecutor extends AbstractExecutor { - + protected File worldDir; + protected File tempDir; + @Override public boolean execute(ExecutorArgs args) { - RenderingExecutorArgs renderingArgs = (RenderingExecutorArgs)args; - - File worldDir = new File(renderingArgs.getWorldPath()); - File tempDir = new File(worldDir, "TEMP"); + RenderingExecutorArgs renderingArgs = (RenderingExecutorArgs) args; + + worldDir = new File(renderingArgs.getWorldPath()); + tempDir = new File(worldDir, "TEMP"); tempDir.deleteOnExit(); - boolean overwrite = renderingArgs.isSilentOverwriteEnabled(); - - if(worldDir.exists() && worldDir.isDirectory()) { - if(!overwrite) { - print(false, Resources.get("world_already_exists"), tempDir.getAbsolutePath()); - Scanner in = new Scanner(System.in); - String input = ""; - while(!input.equalsIgnoreCase("Y") && !input.equalsIgnoreCase("N")) { - input = in.next(); - } - in.close(); - if(input.equalsIgnoreCase("Y")) { - overwrite = true; - } else { - print(Resources.get("render_interrupted")); - return false; - } - } - if(overwrite) { - FileUtils.deleteDirectory(worldDir); - } - } - + + generateWorldDir(renderingArgs.isSilentOverwriteEnabled()); + try { boolean isValid = CmxmlValidator.validate(renderingArgs.getInputFile()); - if(!isValid) { + if (!isValid) { throw new CmxmlValidationFailedException(); } } catch (IOException e) { @@ -63,22 +44,22 @@ public boolean execute(ExecutorArgs args) { printError(e, Resources.get("invalid_input_xml_error")); return false; } - - WorldBuilder worldBuilder = new WorldBuilder(renderingArgs.getWorldPath()); - for(EventListener listener : listeners) { + + WorldBuilder worldBuilder = new WorldBuilder(renderingArgs.getWorldPath(), renderingArgs.getInputFile()); + for (EventListener listener : listeners) { worldBuilder.addEventListener((ProgressEventListener) listener); } - + print(Resources.get("rendering_reading_input")); try { worldBuilder.createBuildings(renderingArgs.getInputFile()); - } catch (BuildingTypeMismatchException e) { + } catch (Exception e) { printError(e, Resources.get("building_creation_failed_error")); return false; } print(Resources.get("rendering_reading_input_done")); print(Resources.get("buildables_found"), worldBuilder.getNumberOfBuildings()); - + print(Resources.get("creating_blocks")); try { worldBuilder.createBlocks(tempDir, renderingArgs.getMaxTime()); @@ -88,10 +69,10 @@ public boolean execute(ExecutorArgs args) { } long elapsed = worldBuilder.getTimeElapsedDuringLastPhase(); int hours = (int) (elapsed / (1000 * 60 * 60)); - int minutes = (int) (elapsed % (1000 * 60 * 60) / (1000 * 60)); - print(Resources.get("creating_blocks_done"), worldBuilder.getNumberOfBlocks(), hours, minutes); - - print(Resources.get("placing_blocks")); + int minutes = (int) (elapsed % (1000 * 60 * 60) / (1000 * 60)); + print(Resources.get("creating_blocks_done"), worldBuilder.getNumberOfBlocks(), hours, minutes); + + print(Resources.get("placing_blocks")); try { worldBuilder.build(tempDir); } catch (RenderingException e) { @@ -100,22 +81,59 @@ public boolean execute(ExecutorArgs args) { } elapsed = worldBuilder.getTimeElapsedDuringLastPhase(); hours = (int) (elapsed / (1000 * 60 * 60)); - minutes = (int) (elapsed % (1000 * 60 * 60) / (1000 * 60)); - print(Resources.get("placing_blocks_done"), hours, minutes); - - return true; + minutes = (int) (elapsed % (1000 * 60 * 60) / (1000 * 60)); + print(Resources.get("placing_blocks_done"), hours, minutes); + + return true; + } + + protected boolean generateWorldDir(boolean overwrite) { + if (worldDir.exists() && worldDir.isDirectory()) { + if (!overwrite) { + print(false, Resources.get("world_already_exists"), tempDir.getAbsolutePath()); + if (overridePermission()) { + FileUtils.deleteDirectory(worldDir); + } else { + print(Resources.get("render_interrupted")); + return false; + } + } + if (overwrite) { + FileUtils.deleteDirectory(worldDir); + } + } + return true; } - - //region PROGRESS EVENT + + public boolean overridePermission() { + + Scanner in = new Scanner(System.in); + String input = ""; + while (!input.equalsIgnoreCase("Y") && !input.equalsIgnoreCase("N")) { + input = in.next(); + } + in.close(); + if (input.equalsIgnoreCase("Y")) { + return true; + } else { + return false; + } + } + + // region PROGRESS EVENT private List listeners = new ArrayList(); - - public synchronized void addEventListener(ProgressEventListener listener) { + + public int getListenerCount() { + return listeners.size(); + } + + public synchronized void addEventListener(ProgressEventListener listener) { listeners.add(listener); } - - public synchronized void removeEventListener(ProgressEventListener listener) { + + public synchronized void removeEventListener(ProgressEventListener listener) { listeners.remove(listener); } - //endregion - + // endregion + } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/RenderingExecutorArgs.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/RenderingExecutorArgs.java index d6b26410..cc85b7f4 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/RenderingExecutorArgs.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/RenderingExecutorArgs.java @@ -8,7 +8,7 @@ public class RenderingExecutorArgs extends ExecutorArgs { private String worldPath; private boolean overwriteSilently; private int maxTime; - + public RenderingExecutorArgs(String inputFile, String worldPath) { this(inputFile, worldPath, false); } @@ -16,7 +16,7 @@ public RenderingExecutorArgs(String inputFile, String worldPath) { public RenderingExecutorArgs(String inputFile, String worldPath, boolean overwriteSilently) { this(inputFile, worldPath, overwriteSilently, Integer.MAX_VALUE); } - + public RenderingExecutorArgs(String inputFile, String worldPath, boolean overwriteSilently, int maxTime) { super(); this.inputFile = inputFile; diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/Chunk.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/Chunk.java new file mode 100644 index 00000000..e3f0697c --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/Chunk.java @@ -0,0 +1,753 @@ +package codemetropolis.toolchain.rendering.control; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.stream.Stream; +public class Chunk { + + public NBTTag tag; + + private Chunk(NBTTag tag) { + if (tag.getType() != NBTTag.Type.TAG_Compound) { + throw new IllegalArgumentException("Chunk tag must be compound."); + } + this.tag = tag; + } + + public Chunk(int x, int z) { + + byte terrainPopulated = 1; + long inhabitedTime = 0L; + long lastUpdate = 0L; + + int[] heightMap = new int[256]; + Arrays.fill(heightMap, 0); + + NBTTag terrainPopulatedTag = new NBTTag(NBTTag.Type.TAG_Byte, "TerrainPopulated", terrainPopulated); + NBTTag xPosTag = new NBTTag(NBTTag.Type.TAG_Int, "xPos", x); + NBTTag zPosTag = new NBTTag(NBTTag.Type.TAG_Int, "zPos", z); + NBTTag statusTag = new NBTTag(NBTTag.Type.TAG_String, "Status", "empty"); + NBTTag inhabitedTimeTag = new NBTTag(NBTTag.Type.TAG_Long, "InhabitedTime", inhabitedTime); + NBTTag lastUpdateTag = new NBTTag(NBTTag.Type.TAG_Long, "LastUpdate", lastUpdate); + NBTTag entitiesTag = new NBTTag(NBTTag.Type.TAG_List, "Entities", NBTTag.Type.TAG_Byte); + NBTTag tileEntitiesTag = new NBTTag(NBTTag.Type.TAG_List, "TileEntities", NBTTag.Type.TAG_Byte); + NBTTag heightMapTag = new NBTTag(NBTTag.Type.TAG_Int_Array, "HeightMap", heightMap); + NBTTag sectionsTag = new NBTTag("Sections", NBTTag.Type.TAG_List); + NBTTag tileTicksTag = new NBTTag("TileTicks", NBTTag.Type.TAG_List); + + NBTTag[] tagList = new NBTTag[] { xPosTag, terrainPopulatedTag, zPosTag, inhabitedTimeTag, statusTag, + lastUpdateTag, sectionsTag, entitiesTag, tileEntitiesTag, heightMapTag, tileTicksTag, NBTTag.END_TAG }; + NBTTag levelTag = new NBTTag(NBTTag.Type.TAG_Compound, "Level", tagList); + // NBTTag dataVersion = new NBTTag(NBTTag.Type.TAG_Int, "DataVersion", 1631); + this.tag = new NBTTag(NBTTag.Type.TAG_Compound, "", + new NBTTag[] { levelTag/* , dataVersion */, NBTTag.END_TAG }); + + } + + public static Chunk parseNBT(NBTTag t) { + return new Chunk(t); + } + + public NBTTag toNBT() { + return tag; + } + + public void setBiome(int biomeId){ + int[] biomes = new int[256]; + Arrays.fill(biomes, biomeId); + //NBTTag biomeTag = new NBTTag(NBTTag.Type.TAG_String, "biome", biomeId); + NBTTag biomeTag = new NBTTag(NBTTag.Type.TAG_Int_Array, "Biomes", biomes); + tag.getSubtagByName("Level").addTag(biomeTag); + } + + public void setBlock(int x, int y, int z, String blockId, Map blockProperties) { + setBlock(x, y, z, blockId, PropertiesToTags(blockProperties)); + } + public void setBlock(int x, int y, int z, String blockId, NBTTag[] blockProperties) { + int index = y >> 4; + NBTTag section = getSection(index); + if (section == null) { + section = addSection(index); + } + + int blockIndex = (y % 16) * 256 + z * 16 + x; + + long[] blockStates = (long[]) section.getSubtagByName("BlockStates").getValue(); + NBTTag palette = section.getSubtagByName("Palette"); + + long paletteIndex = getIndexFromPalette(palette, blockId, blockProperties); + int numberOfBitsUsedToRepresentPalette; + + int cX = (int) tag.getSubtagByName("Level").getSubtagByName("xPos").getValue(); + int cZ = (int) tag.getSubtagByName("Level").getSubtagByName("zPos").getValue(); + + if (paletteIndex == -1) { + int oldNumberOfBitsUsedToRepresentPalette = getNumberOfBitsUsedToRepresentPalette(palette); + + paletteIndex = insertIntoPalette(palette, blockId, blockProperties); + + numberOfBitsUsedToRepresentPalette = getNumberOfBitsUsedToRepresentPalette(palette); + if (oldNumberOfBitsUsedToRepresentPalette != numberOfBitsUsedToRepresentPalette) { + + //int cY = y/16; + //System.out.println("ChangeBlockStateBitRepresentation("+x+" "+y%16+" "+z+" in "+cX+" "+cY+" "+cZ+" ["+(cX*16+x)+" "+y+" "+(cZ*16+z)+"], bId:"+blockId+", from:"+oldNumberOfBitsUsedToRepresentPalette+", to:"+numberOfBitsUsedToRepresentPalette+")"); + + blockStates = changeBlockStateBitRepresentation(blockStates, 4096, + oldNumberOfBitsUsedToRepresentPalette, numberOfBitsUsedToRepresentPalette); + section.getSubtagByName("BlockStates").setValue(blockStates); + } + } else { + numberOfBitsUsedToRepresentPalette = getNumberOfBitsUsedToRepresentPalette(palette); + } + + setBlockState(blockStates, blockIndex, paletteIndex, numberOfBitsUsedToRepresentPalette); + + int[] heightMap = (int[]) tag.getSubtagByName("Level").getSubtagByName("HeightMap").getValue(); + + if (heightMap[z * 16 + x] < y + 1) + heightMap[z * 16 + x] = y + 1; + + if (blockId.equals("minecraft:repeating_command_block")) { + NBTTag blockIdTag = new NBTTag(NBTTag.Type.TAG_String, "i", blockId); + NBTTag delayTag = new NBTTag(NBTTag.Type.TAG_Int, "t", new Random().nextInt(10)); + NBTTag priorityTag = new NBTTag(NBTTag.Type.TAG_Int, "p", 0); + NBTTag posXTag = new NBTTag(NBTTag.Type.TAG_Int, "x", cX * 16 + x); + NBTTag posYTag = new NBTTag(NBTTag.Type.TAG_Int, "y", y); + NBTTag posZTag = new NBTTag(NBTTag.Type.TAG_Int, "z", cZ * 16 + z); + NBTTag tileTickTag = new NBTTag(NBTTag.Type.TAG_Compound, "", + new NBTTag[] { blockIdTag, delayTag, priorityTag, posXTag, posYTag, posZTag, NBTTag.END_TAG }); + + tag.getSubtagByName("Level").getSubtagByName("TileTicks").addTag(tileTickTag); + } + } + + public String getBlockId(int x, int y, int z) { + int index = y >> 4; + NBTTag section = getSection(index); + if (section == null) { + section = addSection(index); + } + + long[] blockStates = (long[]) section.getSubtagByName("BlockStates").getValue(); + NBTTag palette = section.getSubtagByName("Palette"); + int numberOfBitsUsedToRepresentPalette = getNumberOfBitsUsedToRepresentPalette(palette); + int blockIndex = (y % 16) * 256 + z * 16 + x; + + return (String) palette + .getSubtags()[(int) getBlockState(blockStates, blockIndex, numberOfBitsUsedToRepresentPalette)] + .getSubtagByName("Name").getValue(); + } + + public static long getIndexFromPalette(NBTTag palette, String blockId, NBTTag[] blockProperties) { + NBTTag[] subtags = palette.getSubtags(); + + tagsLoop: for (int i = 0; i < subtags.length; i++) { + NBTTag t = subtags[i]; + + if (t.getSubtagByName("Name").getValue().equals(blockId)) { + NBTTag propertiesTag = t.getSubtagByName("Properties"); + + if( propertiesTag == null || propertiesTag.getValue() == null || ((NBTTag[]) propertiesTag.getValue()).length == 0 ) { + if( blockProperties == null || blockProperties.length == 0 ) { + return i; + }else { + return -1; + } + } + + NBTTag[] properties = (NBTTag[]) propertiesTag.getValue(); + + if (blockProperties.length != properties.length) { + continue; + } + + expectedLoop: for (NBTTag expected : blockProperties) { + for (NBTTag given : properties) { + String expectedName = expected.getName(); + String givenName = given.getName(); + if (expectedName == null || givenName == null) { + if (expectedName != givenName) { + continue; + } else { + continue expectedLoop; + } + + } + if (!expectedName.equals(givenName)) { + continue; + } + + String expectedValue = (String) expected.getValue(); + String givenValue = (String) given.getValue(); + + if ((expectedValue == null || givenValue == null) && expectedValue != givenValue) { + continue; + } + if (!expectedValue.equals(givenValue)) { + continue; + } + + continue expectedLoop; + } + continue tagsLoop; + } + return i; + } + } + return -1; + } + + public static long insertIntoPalette(NBTTag palette, String blockId, NBTTag[] blockProperties) { + if (0 < blockProperties.length + && blockProperties[blockProperties.length - 1].getType() != NBTTag.Type.TAG_End) { + throw new IllegalArgumentException("BlockProperties must be empty or have a TAG_End type item at the end."); + } + + NBTTag blockNameTag = new NBTTag(NBTTag.Type.TAG_String, "Name", blockId); + NBTTag[] blockStateTagList; + if (blockProperties.length > 1) { + NBTTag blockPropertiesTag = new NBTTag(NBTTag.Type.TAG_Compound, "Properties", blockProperties); + blockStateTagList = new NBTTag[] { blockNameTag, blockPropertiesTag, NBTTag.END_TAG }; + } else { + blockStateTagList = new NBTTag[] { blockNameTag, NBTTag.END_TAG }; + } + NBTTag blockStateTag = new NBTTag(NBTTag.Type.TAG_Compound, "", blockStateTagList); + + palette.addTag(blockStateTag); + return palette.getSubtags().length - 1; + } + + public static int getNumberOfBitsUsedToRepresentPalette(NBTTag palette) { + int elements = palette.getSubtags().length; + double log2 = Math.log(elements) / Math.log(2); + int bitsNeeded = (int) Math.ceil(log2); + return Math.max(4, bitsNeeded); + } + + public static void setBlockState(long[] blockStates, int index, long value, int numberOfUsedBits) { + if (numberOfUsedBits < 4) { + throw new IllegalArgumentException("Number of used bits must not be less than 4"); + } + + int startBit = index * numberOfUsedBits; + int startELement = startBit / 64; + int startBitOfElement = startBit - (startELement * 64); + + int elementIndex = startELement; + int bitIndex = startBitOfElement; + int bitsLeft = numberOfUsedBits; + + while (true) { + long mask = createMask(bitIndex, bitsLeft); + + long toBeInserted = value << bitIndex; + blockStates[elementIndex] = (blockStates[elementIndex] & mask) | toBeInserted; + + int insertedBits = 64 - bitIndex; + if (insertedBits < bitsLeft) { + elementIndex++; + bitIndex = 0; + bitsLeft -= insertedBits; + value >>>= insertedBits; + } else { + break; + } + } + } + + public static long createMask(int start, int length) { + long mask = 0; + + if (start > 0) { + mask |= 0xFFFFFFFFFFFFFFFFL >>> (64 - start); + } + + if (start + length < 64) { + mask |= 0xFFFFFFFFFFFFFFFFL << (start + length); + } + + return mask; + } + + public static long createInverseMask(int start, int length) { + return ~createMask(start, length); + } + + public static long getBlockState(long[] blockStates, int index, int numberOfUsedBits) { + if (numberOfUsedBits < 4) { + throw new IllegalArgumentException("Number of used bits must not be less than 4"); + } + + long value = 0; + + int startBit = index * numberOfUsedBits; + int startELement = startBit / 64; + int startBitOfElement = startBit - (startELement * 64); + + int elementIndex = startELement; + int bitIndex = startBitOfElement; + int bitsLeft = numberOfUsedBits; + + while (true) { + long mask = createInverseMask(bitIndex, bitsLeft); + long masked = blockStates[elementIndex] & mask; + long maskedAligned = masked >>> bitIndex; + value |= maskedAligned << (numberOfUsedBits - bitsLeft); + + int readBits = 64 - bitIndex; + if (readBits < bitsLeft) { + elementIndex++; + bitIndex = 0; + bitsLeft -= readBits; + } else { + break; + } + } + + return value; + } + + public static long[] changeBlockStateBitRepresentation(long[] oldBlockStates, int numberOfBlocks, int oldUsedBits, + int newUsedBits) { + int newBlockStatesSize = (int)Math.ceil((numberOfBlocks * newUsedBits) / 64f); + long[] newBlockStates = new long[newBlockStatesSize]; + for (int i = 0; i < numberOfBlocks; i++) { + long value = getBlockState(oldBlockStates, i, oldUsedBits); + setBlockState(newBlockStates, i, value, newUsedBits); + } + return newBlockStates; + } + + private String toTextJson(String text) { + return String.format("{\"text\":\"%s\"}", text); + } + + public void setSignText(int x, int y, int z, String text) { + + String[] texts = new String[4]; + for (int i = 0; i < 4; i++) { + if (text.length() > 15) { + texts[i] = text.substring(0, 14); + text = text.substring(14); + } else if (text.length() > 0) { + texts[i] = text.substring(0); + text = ""; + } else { + texts[i] = ""; + } + + texts[i] = toTextJson(texts[i]); + } + + NBTTag tileEntities = tag.getSubtagByName("Level").getSubtagByName("TileEntities"); + for (NBTTag t : (NBTTag[]) tileEntities.getValue()) { + if ((int) t.getSubtagByName("x").getValue() == x && (int) t.getSubtagByName("y").getValue() == y + && (int) t.getSubtagByName("z").getValue() == z + && ((String) t.getSubtagByName("id").getValue()).equals("minecraft:sign")) { + + for (int i = 0; i < texts.length; i++) { + t.getSubtagByName("Text" + (i + 1)).setValue(texts[i]); + } + return; + } + } + + NBTTag xTag = new NBTTag(NBTTag.Type.TAG_Int, "x", x); + NBTTag yTag = new NBTTag(NBTTag.Type.TAG_Int, "y", y); + NBTTag zTag = new NBTTag(NBTTag.Type.TAG_Int, "z", z); + NBTTag idTag = new NBTTag(NBTTag.Type.TAG_String, "id", "minecraft:sign"); + NBTTag text1Tag = new NBTTag(NBTTag.Type.TAG_String, "Text1", texts[0]); + NBTTag text2Tag = new NBTTag(NBTTag.Type.TAG_String, "Text2", texts[1]); + NBTTag text3Tag = new NBTTag(NBTTag.Type.TAG_String, "Text3", texts[2]); + NBTTag text4Tag = new NBTTag(NBTTag.Type.TAG_String, "Text4", texts[3]); + NBTTag[] tagList = new NBTTag[] { xTag, yTag, zTag, idTag, text1Tag, text2Tag, text3Tag, text4Tag, + NBTTag.END_TAG }; + NBTTag tileEntityTag = new NBTTag(NBTTag.Type.TAG_Compound, "", tagList); + + tileEntities.addTag(tileEntityTag); + + } + + public void setSpawner(int x, int y, int z) { + NBTTag tileEntities = tag.getSubtagByName("Level").getSubtagByName("TileEntities"); + + NBTTag xTag = new NBTTag(NBTTag.Type.TAG_Int, "x", x); + NBTTag yTag = new NBTTag(NBTTag.Type.TAG_Int, "y", y); + NBTTag zTag = new NBTTag(NBTTag.Type.TAG_Int, "z", z); + NBTTag idTag = new NBTTag(NBTTag.Type.TAG_String, "id", "minecraft:mob_spawner"); + + NBTTag spawnerTag = new NBTTag(NBTTag.Type.TAG_String, "id", "minecraft:villager"); + NBTTag[] tagList2 = new NBTTag[] { spawnerTag, NBTTag.END_TAG }; + NBTTag tileEntityTag2 = new NBTTag(NBTTag.Type.TAG_Compound, "SpawnData", tagList2); + + NBTTag[] tagList = new NBTTag[] { xTag, yTag, zTag, idTag, tileEntityTag2, NBTTag.END_TAG }; + NBTTag tileEntityTag = new NBTTag(NBTTag.Type.TAG_Compound, "", tagList); + tileEntities.addTag(tileEntityTag); + + } + + public void setMob(double x, double y, double z, String name) { + + NBTTag entities = tag.getSubtagByName("Level").getSubtagByName("Entities"); + + NBTTag xTag = new NBTTag(NBTTag.Type.TAG_Double, "x", x); + NBTTag yTag = new NBTTag(NBTTag.Type.TAG_Double, "y", y); + NBTTag zTag = new NBTTag(NBTTag.Type.TAG_Double, "z", z); + NBTTag pos = new NBTTag(NBTTag.Type.TAG_List, "Pos", new NBTTag[]{xTag, yTag, zTag}); +//modositas + NBTTag idTag = new NBTTag(NBTTag.Type.TAG_String, "id", name); + NBTTag noAiTag = new NBTTag(NBTTag.Type.TAG_Byte, "NoAI", (byte)0); + NBTTag[] tagList = new NBTTag[] {pos, idTag, noAiTag, NBTTag.END_TAG}; + NBTTag entityTag = new NBTTag(NBTTag.Type.TAG_Compound, "", tagList); + + entities.addTag(entityTag); + + } + + public void setCommandBlockCommand(int x, int y, int z, String command) { + + NBTTag tileEntities = tag.getSubtagByName("Level").getSubtagByName("TileEntities"); + for (NBTTag t : (NBTTag[]) tileEntities.getValue()) { + if ((int) t.getSubtagByName("x").getValue() == x && (int) t.getSubtagByName("y").getValue() == y + && (int) t.getSubtagByName("z").getValue() == z + && ((String) t.getSubtagByName("id").getValue()).equals("minecraft:command_block")) { + + t.getSubtagByName("Command").setValue(command); + return; + } + } + + NBTTag xTag = new NBTTag(NBTTag.Type.TAG_Int, "x", x); + NBTTag yTag = new NBTTag(NBTTag.Type.TAG_Int, "y", y); + NBTTag zTag = new NBTTag(NBTTag.Type.TAG_Int, "z", z); + NBTTag idTag = new NBTTag(NBTTag.Type.TAG_String, "id", "minecraft:command_block"); + NBTTag commandTag = new NBTTag(NBTTag.Type.TAG_String, "Command", command); + NBTTag lastOutputTag = new NBTTag(NBTTag.Type.TAG_String, "LastOutput", ""); + NBTTag autoTag = new NBTTag(NBTTag.Type.TAG_Byte, "auto", (byte) 1); + NBTTag conditionMetTag = new NBTTag(NBTTag.Type.TAG_Byte, "conditionMet", (byte) 1); + NBTTag keepPackedTag = new NBTTag(NBTTag.Type.TAG_Byte, "keepPacked", (byte) 0); + NBTTag poweredTag = new NBTTag(NBTTag.Type.TAG_Byte, "powered", (byte) 1); + NBTTag successCountTag = new NBTTag(NBTTag.Type.TAG_Int, "SuccessCount", 0); + NBTTag trackOutputTag = new NBTTag(NBTTag.Type.TAG_Byte, "TrackOutput", (byte) 1); + NBTTag updateLastExecutionTag = new NBTTag(NBTTag.Type.TAG_Byte, "UpdateLastExecution", (byte) 1); + NBTTag lastExecutionTag = new NBTTag(NBTTag.Type.TAG_Long, "LastExecution", (long) 0); + NBTTag customNameTag = new NBTTag(NBTTag.Type.TAG_String, "CustomName", "{\"text\":\"@\"}"); + + NBTTag[] tagList = new NBTTag[] { xTag, yTag, zTag, idTag, commandTag, lastOutputTag, autoTag, customNameTag, + conditionMetTag, lastExecutionTag, keepPackedTag, poweredTag, successCountTag, trackOutputTag, + updateLastExecutionTag, NBTTag.END_TAG }; + NBTTag tileEntityTag = new NBTTag(NBTTag.Type.TAG_Compound, "", tagList); + + tileEntities.addTag(tileEntityTag); + + } + + public void setBannerColor(int x, int y, int z, int color) { + + NBTTag tileEntities = tag.getSubtagByName("Level").getSubtagByName("TileEntities"); + for (NBTTag t : (NBTTag[]) tileEntities.getValue()) { + if ((int) t.getSubtagByName("x").getValue() == x && (int) t.getSubtagByName("y").getValue() == y + && (int) t.getSubtagByName("z").getValue() == z + && ((String) t.getSubtagByName("id").getValue()).equals("Banner")) { + t.getSubtagByName("Base").setValue(color); + return; + } + } + + NBTTag baseTag = new NBTTag(NBTTag.Type.TAG_Int, "Base", color); + NBTTag xTag = new NBTTag(NBTTag.Type.TAG_Int, "x", x); + NBTTag yTag = new NBTTag(NBTTag.Type.TAG_Int, "y", y); + NBTTag zTag = new NBTTag(NBTTag.Type.TAG_Int, "z", z); + NBTTag idTag = new NBTTag(NBTTag.Type.TAG_String, "id", "Banner"); + NBTTag[] tagList = new NBTTag[] { baseTag, xTag, yTag, zTag, idTag, NBTTag.END_TAG }; + NBTTag tileEntityTag = new NBTTag(NBTTag.Type.TAG_Compound, "", tagList); + + tileEntities.addTag(tileEntityTag); + + } + + public void removeSignText(int x, int y, int z) { + removeTileEntity(x, y, z, "Sign"); + } + + public void addChestItem(int x, int y, int z, int id, int quantity) { + NBTTag tileEntity = getTileEntity(x, y, z, "Chest"); + + if (tileEntity == null) { + NBTTag xTag = new NBTTag(NBTTag.Type.TAG_Int, "x", x); + NBTTag yTag = new NBTTag(NBTTag.Type.TAG_Int, "y", y); + NBTTag zTag = new NBTTag(NBTTag.Type.TAG_Int, "z", z); + NBTTag idTag = new NBTTag(NBTTag.Type.TAG_String, "id", "Chest"); + NBTTag itemsTag = new NBTTag("Items", NBTTag.Type.TAG_Compound); + NBTTag[] tagList = new NBTTag[] { xTag, yTag, zTag, idTag, itemsTag, NBTTag.END_TAG }; + tileEntity = new NBTTag(NBTTag.Type.TAG_Compound, "", tagList); + tag.getSubtagByName("Level").getSubtagByName("TileEntities").addTag(tileEntity); + } + + NBTTag items = tileEntity.getSubtagByName("Items"); + Set usedSlots = new HashSet(); + for (NBTTag t : (NBTTag[]) items.getValue()) { + usedSlots.add((byte) t.getSubtagByName("Slot").getValue()); + } + + for (byte i = 0; i < 27; i++) { + if (!usedSlots.contains(i)) { + NBTTag idTag = new NBTTag(NBTTag.Type.TAG_Short, "id", (short) id); + NBTTag slotTag = new NBTTag(NBTTag.Type.TAG_Byte, "Slot", i); + NBTTag countTag = new NBTTag(NBTTag.Type.TAG_Byte, "Count", (byte) quantity); + NBTTag damageTag = new NBTTag(NBTTag.Type.TAG_Short, "Damage", (short) 0); + NBTTag[] tagList = new NBTTag[] { idTag, slotTag, countTag, damageTag, NBTTag.END_TAG }; + items.addTag(new NBTTag(NBTTag.Type.TAG_Compound, "", tagList)); + return; + } + } + + } + + public void clearChestItems(int x, int y, int z) { + removeTileEntity(x, y, z, "Chest"); + } + + private NBTTag getTileEntity(int x, int y, int z, String id) { + NBTTag tileEntities = tag.getSubtagByName("Level").getSubtagByName("TileEntities"); + for (NBTTag t : (NBTTag[]) tileEntities.getValue()) { + if ((int) t.getSubtagByName("x").getValue() == x && (int) t.getSubtagByName("y").getValue() == y + && (int) t.getSubtagByName("z").getValue() == z + && ((String) t.getSubtagByName("id").getValue()).equals(id)) { + return t; + } + } + return null; + } + + public void removeTileEntity(int x, int y, int z, String id) { + + Set tagsToRemoveIndex = new HashSet(); + NBTTag tileEntities = tag.getSubtagByName("Level").getSubtagByName("TileEntities"); + NBTTag[] tileEntitiesArray = (NBTTag[]) tileEntities.getValue(); + for (int i = 0; i < tileEntitiesArray.length; i++) { + NBTTag t = tileEntitiesArray[i]; + if ((int) t.getSubtagByName("x").getValue() == x && (int) t.getSubtagByName("y").getValue() == y + && (int) t.getSubtagByName("z").getValue() == z) { + if (id == null) { + tagsToRemoveIndex.add(i); + } else if (((String) t.getSubtagByName("id").getValue()).equals(id)) { + tagsToRemoveIndex.add(i); + break; + } + } + } + for (int i : tagsToRemoveIndex) + tileEntities.removeTag(i); + + } + + public void clearTileEntitiesAt(int x, int y, int z) { + removeTileEntity(x, y, z, null); + } + + private NBTTag getSection(int y) { + for (NBTTag t : tag.getSubtagByName("Level").getSubtagByName("Sections").getSubtags()) { + if ((byte) t.getSubtagByName("Y").getValue() == y) { + return t; + } + } + return null; + } + + private NBTTag addSection(int y) { + + byte[] blockLight = new byte[2048]; + Arrays.fill(blockLight, (byte) 0); + + long[] blockStates = new long[256]; + Arrays.fill(blockStates, (long) 0); + + byte[] skyLight = new byte[2048]; + Arrays.fill(skyLight, (byte) 255); + + NBTTag yTag = new NBTTag(NBTTag.Type.TAG_Byte, "Y", (byte) y); + NBTTag paletteTag = new NBTTag("Palette", NBTTag.Type.TAG_List); + insertIntoPalette(paletteTag, "minecraft:air", new NBTTag[0]); + NBTTag blockLightTag = new NBTTag(NBTTag.Type.TAG_Byte_Array, "BlockLight", blockLight); + NBTTag blockStatesTag = new NBTTag(NBTTag.Type.TAG_Long_Array, "BlockStates", blockStates); + NBTTag skyLightTag = new NBTTag(NBTTag.Type.TAG_Byte_Array, "SkyLight", skyLight); + NBTTag[] tagList = new NBTTag[] { yTag, paletteTag, skyLightTag, blockStatesTag, blockLightTag, + NBTTag.END_TAG }; + NBTTag sectionTag = new NBTTag(NBTTag.Type.TAG_Compound, "", tagList); + tag.getSubtagByName("Level").getSubtagByName("Sections").addTag(sectionTag); + + return sectionTag; + } + + public NBTTag addSection(int y, NBTTag palette, long[] blockStates, byte[] skyLight) { + NBTTag section = addSection(y); + + section.removeSubtag(section.getSubtagByName("Palette")); // need to replace, cuz setvalue didn't wanna work + section.addTag(palette); + + section.getSubtagByName("BlockStates").setValue(blockStates); + section.getSubtagByName("SkyLight").setValue(skyLight); + return section; + } + + public NBTTag addSectionFilled(int y, String blockId, NBTTag[] blockProperties, int height) { + + NBTTag palette = new NBTTag("Palette", NBTTag.Type.TAG_List); + long airIndex = 0; + long blockIndex = 0; + + if (height < 16) { + insertIntoPalette(palette, "minecraft:air", new NBTTag[0]); + blockIndex++; + } + insertIntoPalette(palette, blockId, blockProperties); + + long[] blockStates = new long[256]; + byte[] skyLight = new byte[2048]; + + for (int _x = 0; _x < 16; _x++) { + for (int _y = 0; _y < 16; _y++) { + for (int _z = 0; _z < 16; _z++) { + if (_y < height) { + setBlockState(blockStates, _y * 256 + _z * 16 + _x, blockIndex, 4); + } else { + setBlockState(blockStates, _y * 256 + _z * 16 + _x, airIndex, 4); + } + } + } + } + + int[] heightMap = (int[]) tag.getSubtagByName("Level").getSubtagByName("HeightMap").getValue(); + for (int i = 0; i < 256; i++) { + if (heightMap[i] < y * 16 + height) + heightMap[i] = y * 16 + height; + } + + Arrays.fill(skyLight, 0, height * 128, (byte) 0); + Arrays.fill(skyLight, height * 128, 2048, (byte) 255); + + return addSection(y, palette, blockStates, skyLight); + } + + public NBTTag addSectionFilled(int y, String blockId, NBTTag[] blockProperties) { + return addSectionFilled(y, blockId, blockProperties, 16); + } + + public void fill(int y, String blockId, NBTTag[] blockProperties) { + + for (int _y = 0; _y < (y >> 4); _y++) { + addSectionFilled(_y, blockId, blockProperties); + } + addSectionFilled(y >> 4, blockId, blockProperties, y % 16 + 1); + + } + + public void calculateLighting() { + Set lightingObjects = new HashSet<>(); + lightingObjects.add("minecraft:redstone_lamp"); + lightingObjects.add("minecraft:wall_torch"); + + NBTTag[] sectionTags = tag.getSubtagByName("Level").getSubtagByName("Sections").getSubtags(); + for (NBTTag section : sectionTags) { + byte[] skyLight = (byte[]) section.getSubtagByName("SkyLight").getValue(); + byte[] blockLight = (byte[]) section.getSubtagByName("BlockLight").getValue(); + long[] blockStates = (long[]) section.getSubtagByName("BlockStates").getValue(); + NBTTag palette = section.getSubtagByName("Palette"); + int paletteBits = getNumberOfBitsUsedToRepresentPalette(palette); + for (int blockZ = 0; blockZ < 16; blockZ++) + for (int y = 0; y < 16; y++) + for (int blockX = 0; blockX < 16; blockX++) { + // Temporary solution + int paletteId = (int) getBlockState(blockStates, y * 256 + blockZ * 16 + blockX, paletteBits); + String blockId = (String) palette.getSubtags()[paletteId].getSubtagByName("Name").getValue(); + + if (!blockId.equals("minecraft:air")) { + setNibble(skyLight, (y * 256 + blockZ * 16 + blockX), (byte) 15); + if (lightingObjects.contains(blockId)) { + setNibble(blockLight, (y * 256 + blockZ * 16 + blockX), (byte) 15); + setNibble(blockLight, (y * 256 + blockZ * 16 + blockX + 1), (byte) 15); + setNibble(blockLight, (y * 256 + blockZ * 16 + blockX - 1), (byte) 15); + setNibble(blockLight, ((y + 1) * 256 + blockZ * 16 + blockX), (byte) 15); + setNibble(blockLight, ((y - 1) * 256 + blockZ * 16 + blockX), (byte) 15); + setNibble(blockLight, (y * 256 + (blockZ + 1) * 16 + blockX), (byte) 15); + setNibble(blockLight, (y * 256 + (blockZ - 1) * 16 + blockX), (byte) 15); + } + } + + } + section.getSubtagByName("SkyLight").setValue(skyLight); + section.getSubtagByName("BlockLight").setValue(blockLight); + } + } + + public void filterMagicalBlocks() { + NBTTag[] sectionTags = tag.getSubtagByName("Level").getSubtagByName("Sections").getSubtags(); + int chunkX = (int) tag.getSubtagByName("Level").getSubtagByName("xPos").getValue(); + int chunkZ = (int) tag.getSubtagByName("Level").getSubtagByName("zPos").getValue(); + + for (NBTTag section : sectionTags) { + int sectionY = (byte) section.getSubtagByName("Y").getValue(); + + for (int blockZ = 0; blockZ < 16; blockZ++) { + for (int y = 0; y < 16; y++) { + for (int blockX = 0; blockX < 16; blockX++) { + + long[] blockStates = (long[]) section.getSubtagByName("BlockStates").getValue(); + NBTTag palette = section.getSubtagByName("Palette"); + int paletteBits = getNumberOfBitsUsedToRepresentPalette(palette); + + int paletteId = (int) getBlockState(blockStates, y * 256 + blockZ * 16 + blockX, paletteBits); + String blockId = (String) palette.getSubtags()[paletteId].getSubtagByName("Name").getValue(); + + if (blockId.equals("minecraft:oak_fence")) { + int absoluteY = sectionY * 16 + y; + int absoluteX = chunkX * 16 + blockX; + int absoluteZ = chunkZ * 16 + blockZ; + String command = "fill " + absoluteX + " " + absoluteY + " " + absoluteZ + " " + absoluteX + + " " + absoluteY + " " + absoluteZ + " " + blockId; + setBlock(blockX, absoluteY, blockZ, "minecraft:repeating_command_block", new NBTTag[] { + new NBTTag(NBTTag.Type.TAG_String, "conditional", "false"), NBTTag.END_TAG }); + setCommandBlockCommand(absoluteX, absoluteY, absoluteZ, command); + } + + } + } + } + } + } + + public static void setNibble(byte[] a, int index, byte value) { + if (index / 2 < 0 || index / 2 > a.length - 1) + return; + + boolean lastBits = ((double) index / 2) % 1 == 0 ? true : false; + + if (lastBits) { + value = (byte) ((a[index / 2] & 0xF0) | value); + } else { + value = (byte) ((a[index / 2] & 0x0F) | (value << 4)); + } + + a[index / 2] = value; + } + + @Override + public String toString() { + return tag.toString(); + } + + public static NBTTag[] PropertiesToTags(Map properties) { + if (properties.isEmpty()) { + return new NBTTag[0]; + } else { + return Stream.concat( + properties.entrySet().stream() + .map(e -> new NBTTag(NBTTag.Type.TAG_String, e.getKey(), e.getValue())), + Stream.of(NBTTag.END_TAG)).toArray(size -> new NBTTag[size]); + } + } + +} \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/FileHandler.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/FileHandler.java new file mode 100644 index 00000000..3ced309e --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/FileHandler.java @@ -0,0 +1,55 @@ +package codemetropolis.toolchain.rendering.control; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class FileHandler { + + public static void copy(String srcPath, String destPath, String... ignore) { + File sourceLocation = new File(srcPath); + File targetLocation = new File(destPath); + copy(sourceLocation, targetLocation, ignore); + } + + public static void copy(File sourceLocation, File targetLocation, String... ignore) { + for(String s : ignore) + if(sourceLocation.getName().equals(s)) return; + try { + if (sourceLocation.isDirectory()) { + copyDirectory(sourceLocation, targetLocation, ignore); + } else { + copyFile(sourceLocation, targetLocation); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void copyDirectory(File source, File target, String... ignore) throws IOException { + if (!target.exists()) { + target.mkdirs(); + } + + for (String f : source.list()) { + copy(new File(source, f), new File(target, f), ignore); + } + } + + private static void copyFile(File source, File target) throws IOException { + try ( + InputStream in = new FileInputStream(source); + OutputStream out = new FileOutputStream(target) + ) { + byte[] buf = new byte[1024]; + int length; + while ((length = in.read(buf)) > 0) { + out.write(buf, 0, length); + } + } + } + +} \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/Level.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/Level.java new file mode 100644 index 00000000..32797792 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/Level.java @@ -0,0 +1,149 @@ +package codemetropolis.toolchain.rendering.control; + +import java.io.File; +import java.io.IOException; + +public class Level { + + private static final LevelHelper HELPER = new LevelHelper(); + private LevelFile levelFile; + private NBTTag tag; + + public Level(World world) { + File file = new File(String.format("%s/level.dat", world.PATH)); + boolean alreadyExists = file.exists(); + this.levelFile = new LevelFile(file); + + if (alreadyExists) { + + try { + tag = NBTTag.readFrom(levelFile.getLevelDataInputStream()); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + + tag = createNewLevelFile(world); + } + + } + + private NBTTag createNewLevelFile(World world) { + NBTTag versionTag = new NBTTag(NBTTag.Type.TAG_Int, "version", 19133); + NBTTag initializedTag = new NBTTag(NBTTag.Type.TAG_Byte, "initialized", (byte) 1); + NBTTag levelNameTag = new NBTTag(NBTTag.Type.TAG_String, "LevelName", world.NAME); + NBTTag generatorNameTag = new NBTTag(NBTTag.Type.TAG_String, "generatorName", "flat"); + NBTTag generatorVersionTag = new NBTTag(NBTTag.Type.TAG_Int, "generatorVersion", 0); + NBTTag randomSeedTag = new NBTTag(NBTTag.Type.TAG_Long, "RandomSeed", 0L); + NBTTag mapFeaturesTag = new NBTTag(NBTTag.Type.TAG_Byte, "MapFeatures", (byte) 0); + NBTTag lastPlayedTag = new NBTTag(NBTTag.Type.TAG_Long, "LastPlayed", System.currentTimeMillis()); + NBTTag sizeOnDiskTag = new NBTTag(NBTTag.Type.TAG_Long, "SizeOnDisk", 0L); + NBTTag allowCommandsTag = new NBTTag(NBTTag.Type.TAG_Byte, "allowCommands", (byte) 1); + NBTTag hardcoreTag = new NBTTag(NBTTag.Type.TAG_Byte, "hardcore", (byte) 0); + NBTTag gameTypeTag = new NBTTag(NBTTag.Type.TAG_Int, "GameType", 1); + NBTTag difficultyTag = new NBTTag(NBTTag.Type.TAG_Byte, "Difficulty", (byte) 2); + NBTTag difficultyLockedTag = new NBTTag(NBTTag.Type.TAG_Byte, "DifficultyLocked", (byte) 0); + NBTTag timeTag = new NBTTag(NBTTag.Type.TAG_Long, "Time", 3000L); + NBTTag dayTimeTag = new NBTTag(NBTTag.Type.TAG_Long, "DayTime", 3000L); + NBTTag spawnXTag = new NBTTag(NBTTag.Type.TAG_Int, "SpawnX", 0); + NBTTag spawnYTag = new NBTTag(NBTTag.Type.TAG_Int, "SpawnY", world.GROUNDLEVEL + 1); + NBTTag spawnZTag = new NBTTag(NBTTag.Type.TAG_Int, "SpawnZ", 0); + NBTTag borderCenterXTag = new NBTTag(NBTTag.Type.TAG_Double, "BorderCenterX", (double) 0); + NBTTag borderCenterZTag = new NBTTag(NBTTag.Type.TAG_Double, "BorderCenterZ", (double) 0); + + NBTTag borderSizeTag = new NBTTag(NBTTag.Type.TAG_Double, "BorderSize", (double) 60000000); + NBTTag borderSafeZoneTag = new NBTTag(NBTTag.Type.TAG_Double, "BorderSafeZone", (double) 5); + NBTTag borderWarningBlocksTag = new NBTTag(NBTTag.Type.TAG_Double, "BorderWarningBlocks", (double) 5); + NBTTag borderWarningTimeTag = new NBTTag(NBTTag.Type.TAG_Double, "BorderWarningTime", (double) 15); + NBTTag borderSizeLerpTargetTag = new NBTTag(NBTTag.Type.TAG_Double, "BorderSizeLerpTarget", (double) 60000000); + NBTTag borderSizeLerpTimeTag = new NBTTag(NBTTag.Type.TAG_Long, "BorderSizeLerpTime", 0L); + NBTTag borderDamagePerBlockTag = new NBTTag(NBTTag.Type.TAG_Double, "BorderSizeLerpTarget", 0.2); + + NBTTag dataVersionTag = new NBTTag(NBTTag.Type.TAG_Int, "DataVersion", 1631); + + NBTTag rainingTag = new NBTTag(NBTTag.Type.TAG_Byte, "raining", (byte) 0); + NBTTag rainTimeTag = new NBTTag(NBTTag.Type.TAG_Int, "rainTime", Integer.MAX_VALUE); + NBTTag thunderingTag = new NBTTag(NBTTag.Type.TAG_Byte, "thundering", (byte) 0); + NBTTag thunderTimeTag = new NBTTag(NBTTag.Type.TAG_Int, "thunderTime", Integer.MAX_VALUE); + NBTTag clearWeatherTimeTag = new NBTTag(NBTTag.Type.TAG_Int, "clearWeatherTime", Integer.MAX_VALUE); + + /** + * Gamerules: + * + */ + + NBTTag announceAdvancementsTag = new NBTTag(NBTTag.Type.TAG_String, "announceAdvancements", "true"); + NBTTag commandBlockOutputTag = new NBTTag(NBTTag.Type.TAG_String, "commandBlockOutput", "true"); + NBTTag disableElytraMovementCheckTag = new NBTTag(NBTTag.Type.TAG_String, "disableElytraMovementCheck", "false"); + NBTTag doDaylightCycleTag = new NBTTag(NBTTag.Type.TAG_String, "doDaylightCycle", "false"); + NBTTag doEntityDropsTag = new NBTTag(NBTTag.Type.TAG_String, "doEntityDrops", "true"); + NBTTag doFireTickTag = new NBTTag(NBTTag.Type.TAG_String, "doFireTick", "true"); + NBTTag doLimitedCraftingTag = new NBTTag(NBTTag.Type.TAG_String, "doLimitedCrafting", "false"); + NBTTag doMobLootTag = new NBTTag(NBTTag.Type.TAG_String, "doMobLoot", "true"); + NBTTag doMobSpawningTag = new NBTTag(NBTTag.Type.TAG_String, "doMobSpawning", "false"); + NBTTag doTileDropsTag = new NBTTag(NBTTag.Type.TAG_String, "doTileDrops", "true"); + NBTTag doWeatherCycleTag = new NBTTag(NBTTag.Type.TAG_String, "doWeatherCycle", "true"); + NBTTag keepInventoryTag = new NBTTag(NBTTag.Type.TAG_String, "keepInventory", "true"); + NBTTag logAdminCommandsTag = new NBTTag(NBTTag.Type.TAG_String, "logAdminCommands", "true"); + NBTTag maxCommandChainLengthTag = new NBTTag(NBTTag.Type.TAG_String, "maxCommandChainLength", "65536"); + NBTTag maxEntityCrammingTag = new NBTTag(NBTTag.Type.TAG_String, "maxEntityCramming", "24"); + NBTTag mobGriefingTag = new NBTTag(NBTTag.Type.TAG_String, "mobGriefing", "false"); + NBTTag naturalRegenerationTag = new NBTTag(NBTTag.Type.TAG_String, "naturalRegeneration", "true"); + NBTTag randomTickSpeedTag = new NBTTag(NBTTag.Type.TAG_String, "randomTickSpeed", "3"); + NBTTag reducedDebugInfoTag = new NBTTag(NBTTag.Type.TAG_String, "reducedDebugInfo", "false"); + NBTTag sendCommandFeedbackTag = new NBTTag(NBTTag.Type.TAG_String, "sendCommandFeedback", "true"); + NBTTag showDeathMessagesTag = new NBTTag(NBTTag.Type.TAG_String, "showDeathMessages", "true"); + NBTTag spawnRadiusTag = new NBTTag(NBTTag.Type.TAG_String, "spawnRadius", "10"); + NBTTag spectatorsGenerateChunksTag = new NBTTag(NBTTag.Type.TAG_String, "spectatorsGenerateChunks", "true"); + + NBTTag[] ruleList = new NBTTag[] { announceAdvancementsTag, commandBlockOutputTag, disableElytraMovementCheckTag, doDaylightCycleTag, doEntityDropsTag, doFireTickTag, doLimitedCraftingTag, + doMobLootTag, doMobSpawningTag, doTileDropsTag, doWeatherCycleTag, keepInventoryTag, logAdminCommandsTag, maxCommandChainLengthTag, maxEntityCrammingTag, mobGriefingTag, + naturalRegenerationTag, randomTickSpeedTag, reducedDebugInfoTag, sendCommandFeedbackTag, showDeathMessagesTag, spawnRadiusTag, spectatorsGenerateChunksTag, + new NBTTag(NBTTag.Type.TAG_End, null, null) }; + + NBTTag gameRulesTag = new NBTTag(NBTTag.Type.TAG_Compound, "GameRules", ruleList); + + /** + * Version: + */ + + NBTTag versionIdTag = new NBTTag(NBTTag.Type.TAG_Int, "Id", 1631); + NBTTag versionNameTag = new NBTTag(NBTTag.Type.TAG_String, "Name", "1.13.2"); + NBTTag isSnapshotTag = new NBTTag(NBTTag.Type.TAG_Byte, "Snapshot", (byte) 0); + + NBTTag[] versionParameters = new NBTTag[] { versionIdTag, versionNameTag, isSnapshotTag, NBTTag.END_TAG }; + NBTTag version = new NBTTag(NBTTag.Type.TAG_Compound, "Version", versionParameters); + + /** + * Generator options: + */ + + NBTTag structureTag = new NBTTag(NBTTag.Type.TAG_Compound, "structures", new NBTTag[] { NBTTag.END_TAG }); + NBTTag biomeTag = new NBTTag(NBTTag.Type.TAG_String, "biome", "minecraft:desert"); + + NBTTag layers = new NBTTag("layers", NBTTag.Type.TAG_List); + layers.addTag(HELPER.getLayerTagByBlockAndHeight("minecraft:bedrock", (byte) 1)); + layers.addTag(HELPER.getLayerTagByBlockAndHeight("minecraft:dirt", (byte) (world.GROUNDLEVEL - 1))); + layers.addTag(HELPER.getLayerTagByBlockAndHeight("minecraft:grass_block", (byte) 1)); + + NBTTag generatorOptionsTag = new NBTTag(NBTTag.Type.TAG_Compound, "generatorOptions", new NBTTag[] { structureTag, biomeTag, layers, NBTTag.END_TAG }); + + NBTTag[] tagList = new NBTTag[] { versionTag, dataVersionTag,difficultyTag, difficultyLockedTag, borderCenterXTag, initializedTag, clearWeatherTimeTag, borderDamagePerBlockTag, borderSizeLerpTimeTag, + borderCenterZTag, borderWarningBlocksTag, borderSizeLerpTargetTag, borderWarningTimeTag, borderSafeZoneTag, borderSizeTag, levelNameTag, generatorNameTag, generatorVersionTag, + generatorOptionsTag, randomSeedTag, mapFeaturesTag, lastPlayedTag, sizeOnDiskTag, allowCommandsTag, hardcoreTag, gameTypeTag, timeTag, dayTimeTag, spawnXTag, spawnYTag, spawnZTag, rainingTag, + rainTimeTag, thunderingTag, thunderTimeTag, gameRulesTag, version, NBTTag.END_TAG }; + + NBTTag dataTag = new NBTTag(NBTTag.Type.TAG_Compound, "Data", tagList); + return new NBTTag(NBTTag.Type.TAG_Compound, "", new NBTTag[] { dataTag, NBTTag.END_TAG }); + } + + public void writeToFile() { + try { + tag.writeTo(levelFile.getLevelDataOutputStream()); + levelFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/LevelFile.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/LevelFile.java new file mode 100644 index 00000000..13829381 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/LevelFile.java @@ -0,0 +1,44 @@ +package codemetropolis.toolchain.rendering.control; + +import java.io.*; +import java.util.zip.*; + +public class LevelFile { + + private final File fileName; + private RandomAccessFile file; + + public LevelFile(File path) { + fileName = path; + path.getParentFile().mkdirs(); + try { + file = new RandomAccessFile(path, "rw"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public synchronized DataInputStream getLevelDataInputStream() { + try { + byte[] data = new byte[(int) file.length()]; + file.read(data); + return new DataInputStream(new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(data)))); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public DataOutputStream getLevelDataOutputStream() { + try { + return new DataOutputStream(new GZIPOutputStream(new FileOutputStream(fileName))); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public void close() throws IOException { + file.close(); + } +} diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/LevelHelper.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/LevelHelper.java new file mode 100644 index 00000000..ce79e953 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/LevelHelper.java @@ -0,0 +1,23 @@ +package codemetropolis.toolchain.rendering.control; +//import codemetropolis.toolchain.rendering.control.NBTTag; +import java.util.Objects; + +public class LevelHelper { + + /** + * Generates a compound tag that describes one layer. + * + * @param block the layer's desired block + * @param height the desired height + * @return an unnamed TAG_Compound NBT tag, consisting a TAG_String (block) and + * a TAG_Byte (height) + */ + public NBTTag getLayerTagByBlockAndHeight(String block, byte height) { + Objects.requireNonNull(block, "The block cannot be null."); + NBTTag blockTag = new NBTTag(NBTTag.Type.TAG_String, "block", block); + NBTTag heightTag = new NBTTag(NBTTag.Type.TAG_Byte, "height", height); + + return new NBTTag(NBTTag.Type.TAG_Compound, "", new NBTTag[]{blockTag, heightTag, NBTTag.END_TAG}); + } + +} \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/NBTException.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/NBTException.java new file mode 100644 index 00000000..ba0c266f --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/NBTException.java @@ -0,0 +1,29 @@ +package codemetropolis.toolchain.rendering.control; + +public class NBTException extends Exception { + + private static final long serialVersionUID = 1L; + + public NBTException() { + super(); + } + + public NBTException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public NBTException(String message, Throwable cause) { + super(message, cause); + } + + public NBTException(String message) { + super(message); + } + + public NBTException(Throwable cause) { + super(cause); + } + + + +} diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/NBTTag.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/NBTTag.java new file mode 100644 index 00000000..2f287780 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/NBTTag.java @@ -0,0 +1,544 @@ +package codemetropolis.toolchain.rendering.control; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class NBTTag { + + public static final NBTTag END_TAG = new NBTTag(Type.TAG_End, null, null); + + private final Type type; + private Type listType = null; + private final String name; + private Object value; + + public enum Type { + TAG_End, + TAG_Byte, + TAG_Short, + TAG_Int, + TAG_Long, + TAG_Float, + TAG_Double, + TAG_Byte_Array, + TAG_String, + TAG_List, + TAG_Compound, + TAG_Int_Array, + TAG_Long_Array + } + + /** + * Create a new TAG_List or TAG_Compound NBT tag. + * + * @param type either TAG_List or TAG_Compound + * @param name name for the new tag or null to create an unnamed tag. + * @param value list of tags to add to the new tag. + */ + public NBTTag(Type type, String name, NBTTag[] value) { + this(type, name, (Object) value); + } + + /** + * Create a new TAG_List with an empty list. Use {@link NBTTag#addTag(NBTTag)} to add tags later. + * + * @param name name for this tag or null to create an unnamed tag. + * @param listType type of the elements in this empty list. + */ + public NBTTag(String name, Type listType) { + this(Type.TAG_List, name, listType); + } + + /** + * Create a new NBT tag. + * + * @param type any value from the {@link Type} enum. + * @param name name for the new tag or null to create an unnamed tag. + * @param value an object that fits the tag type or a {@link Type} to create an empty TAG_List with this list type. + */ + public NBTTag(Type type, String name, Object value) { + switch (type) { + case TAG_End: + if (value != null) + throw new IllegalArgumentException(); + break; + case TAG_Byte: + if (!(value instanceof Byte)) + throw new IllegalArgumentException(); + break; + case TAG_Short: + if (!(value instanceof Short)) + throw new IllegalArgumentException(); + break; + case TAG_Int: + if (!(value instanceof Integer)) + throw new IllegalArgumentException(); + break; + case TAG_Long: + if (!(value instanceof Long)) + throw new IllegalArgumentException(); + break; + case TAG_Float: + if (!(value instanceof Float)) + throw new IllegalArgumentException(); + break; + case TAG_Double: + if (!(value instanceof Double)) + throw new IllegalArgumentException(); + break; + case TAG_Byte_Array: + if (!(value instanceof byte[])) + throw new IllegalArgumentException(); + break; + case TAG_String: + if (!(value instanceof String)) + throw new IllegalArgumentException(); + break; + case TAG_List: + if (value instanceof Type) { + this.listType = (Type) value; + value = new NBTTag[0]; + } else { + if (!(value instanceof NBTTag[])) + throw new IllegalArgumentException(); + this.listType = (((NBTTag[]) value)[0]).getType(); + } + break; + case TAG_Compound: + if (!(value instanceof NBTTag[])) + throw new IllegalArgumentException(); + break; + case TAG_Int_Array: + if (!(value instanceof int[])) + throw new IllegalArgumentException(); + break; + case TAG_Long_Array: + if (!(value instanceof long[])) + throw new IllegalArgumentException(); + break; + default: + throw new IllegalArgumentException(); + } + this.type = type; + this.name = name; + this.value = value; + } + + public Type getType() { + return type; + } + + public String getName() { + return name; + } + + public Object getValue() { + return value; + } + + public void setValue(Object newValue) + { + switch (type) { + case TAG_End: + if (value != null) + throw new IllegalArgumentException(); + break; + case TAG_Byte: + if (!(value instanceof Byte)) + throw new IllegalArgumentException(); + break; + case TAG_Short: + if (!(value instanceof Short)) + throw new IllegalArgumentException(); + break; + case TAG_Int: + if (!(value instanceof Integer)) + throw new IllegalArgumentException(); + break; + case TAG_Long: + if (!(value instanceof Long)) + throw new IllegalArgumentException(); + break; + case TAG_Float: + if (!(value instanceof Float)) + throw new IllegalArgumentException(); + break; + case TAG_Double: + if (!(value instanceof Double)) + throw new IllegalArgumentException(); + break; + case TAG_Byte_Array: + if (!(value instanceof byte[])) + throw new IllegalArgumentException(); + break; + case TAG_String: + if (!(value instanceof String)) + throw new IllegalArgumentException(); + break; + case TAG_List: + if (value instanceof Type) { + this.listType = (Type) value; + value = new NBTTag[0]; + } else { + if (!(value instanceof NBTTag[])) + throw new IllegalArgumentException(); + this.listType = (((NBTTag[]) value)[0]).getType(); + } + break; + case TAG_Compound: + if (!(value instanceof NBTTag[])) + throw new IllegalArgumentException(); + break; + case TAG_Int_Array: + if (!(value instanceof int[])) + throw new IllegalArgumentException(); + break; + case TAG_Long_Array: + if (!(value instanceof long[])) + throw new IllegalArgumentException(); + break; + default: + throw new IllegalArgumentException(); + } + + value = newValue; + } + + public void clearList() { + value = new NBTTag[0]; + } + + public Type getListType() { + return listType; + } + + /** + * Add a tag to a TAG_List or a TAG_Compound. + */ + public void addTag(NBTTag tag) { + if (type != Type.TAG_List && type != Type.TAG_Compound) + throw new RuntimeException(); + NBTTag[] subtags = (NBTTag[]) value; + + int index = subtags.length; + + //For TAG_Compund entries, we need to add the tag BEFORE the end, + //or the new tag gets placed after the TAG_End, messing up the data. + //TAG_End MUST be kept at the very end of the TAG_Compound. + if(type == Type.TAG_Compound) index--; + insertTag(tag, index); + } + + /** + * Add a tag to a TAG_List or a TAG_Compound at the specified index. + */ + public void insertTag(NBTTag tag, int index) { + if (type != Type.TAG_List && type != Type.TAG_Compound) + throw new RuntimeException(); + NBTTag[] subtags = (NBTTag[]) value; + if (subtags.length > 0) { + if (type == Type.TAG_List && tag.getType() != getListType()) { + throw new IllegalArgumentException(); + } + } else { + if (type == Type.TAG_List) { + listType = tag.getType(); // qqDPS + } + } + if (index > subtags.length) + throw new IndexOutOfBoundsException(); + NBTTag[] newValue = new NBTTag[subtags.length + 1]; + System.arraycopy(subtags, 0, newValue, 0, index); + newValue[index] = tag; + System.arraycopy(subtags, index, newValue, index + 1, subtags.length - index); + value = newValue; + } + + /** + * Remove a tag from a TAG_List or a TAG_Compound at the specified index. + * + * @return the removed tag + */ + public NBTTag removeTag(int index) { + if (type != Type.TAG_List && type != Type.TAG_Compound) + throw new RuntimeException(); + NBTTag[] subtags = (NBTTag[]) value; + NBTTag victim = subtags[index]; + NBTTag[] newValue = new NBTTag[subtags.length - 1]; + System.arraycopy(subtags, 0, newValue, 0, index); + index++; + System.arraycopy(subtags, index, newValue, index - 1, subtags.length - index); + value = newValue; + return victim; + } + + /** + * Remove a tag from a TAG_List or a TAG_Compound. If the tag is not a child of this tag then nested tags are searched. + * + * @param tag tag to look for + */ + public void removeSubtag(NBTTag tag) { + if (type != Type.TAG_List && type != Type.TAG_Compound) + throw new RuntimeException(); + if (tag == null) + return; + NBTTag[] subtags = (NBTTag[]) value; + for (int i = 0; i < subtags.length; i++) { + if (subtags[i] == tag) { + removeTag(i); + return; + } else { + if (subtags[i].type == Type.TAG_List || subtags[i].type == Type.TAG_Compound) { + subtags[i].removeSubtag(tag); + } + } + } + } + + /** + * Find the first nested tag with specified name in a TAG_Compound. + * + * @param name the name to look for. May be null to look for unnamed tags. + * @return the first nested tag that has the specified name. + */ + + public NBTTag getSubtagByName(String name) { + for(NBTTag t : getSubtags()) { + if(name == null || name.equals("")) { + if(t.getName() == null || t.getName().equals("")) return t; + } else { + if(t.getName() != null && t.getName().equals(name)) return t; + } + } + return null; + } + + /** + * Returns an array of all nested tags. + */ + public NBTTag[] getSubtags() { + if (type != Type.TAG_List && type != Type.TAG_Compound) + return null; + return (NBTTag[]) value; + } + + /** + * Read a tag and its nested tags from an InputStream. + * + * @param is stream to read from, like a FileInputStream + * @return NBT tag or structure read from the InputStream + * @throws IOException if there was no valid NBT structure in the InputStream or if another IOException occurred. + */ + public static NBTTag readFrom(InputStream is) throws IOException { + DataInputStream dis = new DataInputStream(is); + byte type = dis.readByte(); + NBTTag tag = null; + + if (type == 0) { + tag = new NBTTag(Type.TAG_End, null, null); + } else { + tag = new NBTTag(Type.values()[type], dis.readUTF(), readPayload(dis, type)); + } + + dis.close(); + + return tag; + } + + private static Object readPayload(DataInputStream dis, byte type) throws IOException { + switch (type) { + case 0: + return null; + case 1: + return dis.readByte(); + case 2: + return dis.readShort(); + case 3: + return dis.readInt(); + case 4: + return dis.readLong(); + case 5: + return dis.readFloat(); + case 6: + return dis.readDouble(); + case 7: + int length = dis.readInt(); + byte[] ba = new byte[length]; + dis.readFully(ba); + return ba; + case 8: + return dis.readUTF(); + case 9: + byte lt = dis.readByte(); + int ll = dis.readInt(); + NBTTag[] lo = new NBTTag[ll]; + for (int i = 0; i < ll; i++) { + lo[i] = new NBTTag(Type.values()[lt], null, readPayload(dis, lt)); + } + if (lo.length == 0) + return Type.values()[lt]; + else + return lo; + case 10: + byte stt; + NBTTag[] tags = new NBTTag[0]; + do { + stt = dis.readByte(); + String name = null; + if (stt != 0) { + name = dis.readUTF(); + } + NBTTag[] newTags = new NBTTag[tags.length + 1]; + System.arraycopy(tags, 0, newTags, 0, tags.length); + newTags[tags.length] = new NBTTag(Type.values()[stt], name, readPayload(dis, stt)); + tags = newTags; } while (stt != 0); + return tags; + case 11: + int len = dis.readInt(); + int[] ia = new int[len]; + for (int qq = 0; qq < len; qq++) { + ia[qq] = dis.readInt(); + } + return ia; + + } + return null; + } + + /** + * Write a tag and its nested tags to an OutputStream. + * + * @param os stream to write to, like a FileOutputStream + * @throws IOException if this is not a valid NBT structure or if any IOException occurred. + */ + public void writeTo(OutputStream os) throws IOException { + DataOutputStream dos = new DataOutputStream(os); + dos.writeByte(type.ordinal()); + if (type != Type.TAG_End) { + if (name != null) { dos.writeUTF(name); } // qqDPS + writePayload(dos); + } + dos.flush(); + dos.close(); + } + + private void writePayload(DataOutputStream dos) throws IOException { + switch (type) { + case TAG_End: + break; + case TAG_Byte: + dos.writeByte((Byte) value); + break; + case TAG_Short: + dos.writeShort((Short) value); + break; + case TAG_Int: + dos.writeInt((Integer) value); + break; + case TAG_Long: + dos.writeLong((Long) value); + break; + case TAG_Float: + dos.writeFloat((Float) value); + break; + case TAG_Double: + dos.writeDouble((Double) value); + break; + case TAG_Byte_Array: + byte[] ba = (byte[]) value; + dos.writeInt(ba.length); + dos.write(ba); + break; + case TAG_String: + dos.writeUTF((String) value); + break; + case TAG_List: + NBTTag[] list = (NBTTag[]) value; + dos.writeByte(getListType().ordinal()); + dos.writeInt(list.length); + for (NBTTag tt : list) { + tt.writePayload(dos); + } + break; + case TAG_Compound: + NBTTag[] subtags = (NBTTag[]) value; + for (NBTTag subtag : subtags) { + Type type = subtag.getType(); + dos.writeByte(type.ordinal()); + if (type != Type.TAG_End) { + dos.writeUTF(subtag.getName()); + subtag.writePayload(dos); + } + } + break; + case TAG_Int_Array: + int[] ia = (int[]) value; + dos.writeInt(ia.length); + for (int qq = 0; qq < ia.length; qq++) { + dos.writeInt(ia[qq]); + } + break; + case TAG_Long_Array: + long[] la = (long[]) value; + dos.writeInt(la.length); + for (int qq = 0; qq < la.length; qq++) { + dos.writeLong(la[qq]); + } + break; + + } + } + + @Override + public String toString() { + return toString(0); + } + + private String toString(int indentLevel) { + if (type == Type.TAG_End) return ""; + NBTTag[] nestedTags = getSubtags(); + StringBuilder sb = new StringBuilder(); + indent(sb, indentLevel); + sb.append(type.toString() + "("); + if(name != null && !name.equals("")) sb.append("\"" + name + "\""); + sb.append(")"); + switch(type) { + case TAG_Byte_Array: + sb.append(" [" + ((byte[])value).length + " bytes]"); + break; + case TAG_Int_Array: + sb.append(" [" + ((int[])value).length + " * 4 bytes]"); + break; + case TAG_Long_Array: + sb.append(" [" + ((long[])value).length + " * 8 bytes]"); + break; + case TAG_List: + sb.append(": " + (nestedTags.length) + " entries"); + break; + case TAG_Compound: + sb.append(": " + (nestedTags.length - 1) + " entries"); + break; + default: + sb.append(": " + value); + } + sb.append("\n"); + if(type == Type.TAG_Compound || type == Type.TAG_List) { + indent(sb, indentLevel); + sb.append("{\n"); + for(NBTTag t : nestedTags) sb.append(t.toString(indentLevel + 1)); + indent(sb, indentLevel); + sb.append("}\n"); + } + return sb.toString(); + } + + private StringBuilder indent(StringBuilder sb, int indentLevel) { + String indent = " "; + for(int i = 0; i < indentLevel; i++) sb.append(indent); + return sb; + } + +} \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/Region.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/Region.java new file mode 100644 index 00000000..4148a330 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/Region.java @@ -0,0 +1,189 @@ +package codemetropolis.toolchain.rendering.control; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +public class Region { + + private int x; + private int z; + RegionFile regionFile; + public Chunk[] chunks = new Chunk[1024]; + + public Region(int x, int z, World world) { + + this.x = x; + this.z = z; + File file = new File(String.format("%s/region/r.%d.%d.mca", world.PATH, x, z)); + file.getParentFile().mkdirs(); + this.regionFile = new RegionFile(file); + + try { + + for(int chunkX = 0; chunkX < 32; chunkX++) { + for(int chunkZ = 0; chunkZ < 32; chunkZ++) { + if(regionFile.hasChunk(chunkX, chunkZ)) { + DataInputStream inputStream = regionFile.getChunkDataInputStream(chunkX, chunkZ); + NBTTag chunkTag = NBTTag.readFrom(inputStream); + Chunk chunk = Chunk.parseNBT(chunkTag); + setChunk(chunkX, chunkZ, chunk); + } + } + } + + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public void setChunk(int x, int z, Chunk c) { + chunks[z * 32 + x] = c; + } + + public Chunk getChunk(int x, int z) { + return chunks[z * 32 + x]; + } + + public static Region loadFromFile(int x, int z, World world) { + return new Region(x, z, world); + } + + public void writeToFile() { + try { + connectNeighbouringFecnes(); + for(int i = 0; i < 1024; i++) { + Chunk c = chunks[i]; + if(c != null) { + DataOutputStream outputStream = regionFile.getChunkDataOutputStream(i % 32, i / 32); + c.calculateLighting(); + //c.filterMagicalBlocks(); + c.toNBT().writeTo(outputStream); + } + } + regionFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void connectNeighbouringFecnes() { + for(int x=0; x<512; x++) { + for(int y=0; y<256; y++) { + for(int z=0; z<512; z++) { + String blockId = getBlockIdAt(x, y, z); + + if( blockId.equals("minecraft:oak_fence") ) { + Map fenceProperties = new HashMap<>(); + + if( z > 0 && getBlockIdAt(x, y, z-1).equals("minecraft:oak_fence") ) { + fenceProperties.put("north", "true"); + } + if( x > 0 && getBlockIdAt(x-1, y, z).equals("minecraft:oak_fence") ) { + fenceProperties.put("west", "true"); + } + if( z < 512-1 && getBlockIdAt(x, y, z+1).equals("minecraft:oak_fence") ) { + fenceProperties.put("south", "true"); + } + if( x < 512-1 && getBlockIdAt(x+1, y, z).equals("minecraft:oak_fence") ) { + fenceProperties.put("east", "true"); + } + + if( !fenceProperties.isEmpty() ) { + setBlockAt(x, y, z, "minecraft:oak_fence", fenceProperties); + } + } + + if( blockId.equals("minecraft:acacia_fence") ) { + Map fenceProperties = new HashMap<>(); + + if( z > 0 && getBlockIdAt(x, y, z-1).equals("minecraft:acacia_fence") ) { + fenceProperties.put("north", "true"); + } + if( x > 0 && getBlockIdAt(x-1, y, z).equals("minecraft:acacia_fence") ) { + fenceProperties.put("west", "true"); + } + if( z < 512-1 && getBlockIdAt(x, y, z+1).equals("minecraft:acacia_fence") ) { + fenceProperties.put("south", "true"); + } + if( x < 512-1 && getBlockIdAt(x+1, y, z).equals("minecraft:acacia_fence") ) { + fenceProperties.put("east", "true"); + } + + if( !fenceProperties.isEmpty() ) { + setBlockAt(x, y, z, "minecraft:acacia_fence", fenceProperties); + } + } + + if( blockId.equals("minecraft:cobblestone_wall") ) { + Map fenceProperties = new HashMap<>(); + + if( z > 0 && getBlockIdAt(x, y, z-1).equals("minecraft:cobblestone_wall") ) { + fenceProperties.put("north", "true"); + } + if( x > 0 && getBlockIdAt(x-1, y, z).equals("minecraft:cobblestone_wall") ) { + fenceProperties.put("west", "true"); + } + if( z < 512-1 && getBlockIdAt(x, y, z+1).equals("minecraft:cobblestone_wall") ) { + fenceProperties.put("south", "true"); + } + if( x < 512-1 && getBlockIdAt(x+1, y, z).equals("minecraft:cobblestone_wall") ) { + fenceProperties.put("east", "true"); + } + + if( !fenceProperties.isEmpty() ) { + setBlockAt(x, y, z, "minecraft:cobblestone_wall", fenceProperties); + } + } + } + } + } + } + + public String getBlockIdAt(int x, int y, int z) { + int chunkX = x >> 4; + int chunkZ = z >> 4; + int chunkIndex = chunkZ * 32 + chunkX; + Chunk chunk = chunks[chunkIndex]; + + if( chunk == null ) { + return ""; + } + + int blockX = x & 0xF; + int blockZ = z & 0xF; + return chunk.getBlockId(blockX, y, blockZ); + } + + public void setBlockAt(int x, int y, int z, String blockId, Map blockProperties) { + int chunkX = x >> 4; + int chunkZ = z >> 4; + int chunkIndex = chunkZ * 32 + chunkX; + Chunk chunk = chunks[chunkIndex]; + int blockX = x & 0xF; + int blockZ = z & 0xF; + chunk.setBlock(blockX, y, blockZ, blockId, blockProperties); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for(Chunk c : chunks) { + if(c != null) + sb.append(c.toString()); + } + return sb.toString(); + } + + public int getX() { + return x; + } + + public int getZ() { + return z; + } + +} \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/RegionFile.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/RegionFile.java new file mode 100644 index 00000000..b829582b --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/RegionFile.java @@ -0,0 +1,375 @@ +package codemetropolis.toolchain.rendering.control; +/* + ** 2011 January 5 + ** + ** The author disclaims copyright to this source code. In place of + ** a legal notice, here is a blessing: + ** + ** May you do good and not evil. + ** May you find forgiveness for yourself and forgive others. + ** May you share freely, never taking more than you give. + **/ + +/* + * 2011 February 16 + * + * This source code is based on the work of Scaevolus (see notice above). + * It has been slightly modified by Mojang AB (constants instead of magic + * numbers, a chunk timestamp header, and auto-formatted according to our + * formatter template). + * + */ + +// Interfaces with region files on the disk + +/* + + Region File Format + + Concept: The minimum unit of storage on hard drives is 4KB. 90% of Minecraft + chunks are smaller than 4KB. 99% are smaller than 8KB. Write a simple + container to store chunks in single files in runs of 4KB sectors. + + Each region file represents a 32x32 group of chunks. The conversion from + chunk number to region number is floor(coord / 32): a chunk at (30, -3) + would be in region (0, -1), and one at (70, -30) would be at (3, -1). + Region files are named "r.x.z.data", where x and z are the region coordinates. + + A region file begins with a 4KB header that describes where chunks are stored + in the file. A 4-byte big-endian integer represents sector offsets and sector + counts. The chunk offset for a chunk (x, z) begins at byte 4*(x+z*32) in the + file. The bottom byte of the chunk offset indicates the number of sectors the + chunk takes up, and the top 3 bytes represent the sector number of the chunk. + Given a chunk offset o, the chunk data begins at byte 4096*(o/256) and takes up + at most 4096*(o%256) bytes. A chunk cannot exceed 1MB in size. If a chunk + offset is 0, the corresponding chunk is not stored in the region file. + + Chunk data begins with a 4-byte big-endian integer representing the chunk data + length in bytes, not counting the length field. The length must be smaller than + 4096 times the number of sectors. The next byte is a version field, to allow + backwards-compatible updates to how chunks are encoded. + + A version of 1 represents a gzipped NBT file. The gzipped data is the chunk + length - 1. + + A version of 2 represents a deflated (zlib compressed) NBT file. The deflated + data is the chunk length - 1. + + */ + +import java.io.*; +import java.util.ArrayList; +import java.util.zip.*; + +public class RegionFile { + + private static final int VERSION_GZIP = 1; + private static final int VERSION_DEFLATE = 2; + + private static final int SECTOR_BYTES = 4096; + private static final int SECTOR_INTS = SECTOR_BYTES / 4; + + static final int CHUNK_HEADER_SIZE = 5; + private static final byte emptySector[] = new byte[4096]; + + private final File fileName; + private RandomAccessFile file; + private final int offsets[]; + private final int chunkTimestamps[]; + private ArrayList sectorFree; + private int sizeDelta; + private long lastModified = 0; + + public RegionFile(File path) { + offsets = new int[SECTOR_INTS]; + chunkTimestamps = new int[SECTOR_INTS]; + + fileName = path; + debugln("REGION LOAD " + fileName); + + sizeDelta = 0; + + try { + if (path.exists()) { + lastModified = path.lastModified(); + } + + file = new RandomAccessFile(path, "rw"); + + if (file.length() < SECTOR_BYTES) { + /* we need to write the chunk offset table */ + for (int i = 0; i < SECTOR_INTS; ++i) { + file.writeInt(0); + } + // write another sector for the timestamp info + for (int i = 0; i < SECTOR_INTS; ++i) { + file.writeInt(0); + } + + sizeDelta += SECTOR_BYTES * 2; + } + + if ((file.length() & 0xfff) != 0) { + /* the file size is not a multiple of 4KB, grow it */ + for (int i = 0; i < (file.length() & 0xfff); ++i) { + file.write((byte) 0); + } + } + + /* set up the available sector map */ + int nSectors = (int) file.length() / SECTOR_BYTES; + sectorFree = new ArrayList(nSectors); + + for (int i = 0; i < nSectors; ++i) { + sectorFree.add(true); + } + + sectorFree.set(0, false); // chunk offset table + sectorFree.set(1, false); // for the last modified info + + file.seek(0); + for (int i = 0; i < SECTOR_INTS; ++i) { + int offset = file.readInt(); + offsets[i] = offset; + if (offset != 0 && (offset >> 8) + (offset & 0xFF) <= sectorFree.size()) { + for (int sectorNum = 0; sectorNum < (offset & 0xFF); ++sectorNum) { + sectorFree.set((offset >> 8) + sectorNum, false); + } + } + } + for (int i = 0; i < SECTOR_INTS; ++i) { + int lastModValue = file.readInt(); + chunkTimestamps[i] = lastModValue; + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + /* the modification date of the region file when it was first opened */ + public long lastModified() { + return lastModified; + } + + /* gets how much the region file has grown since it was last checked */ + public synchronized int getSizeDelta() { + int ret = sizeDelta; + sizeDelta = 0; + return ret; + } + + // various small debug printing helpers + private void debug(String in) { +// System.out.print(in); + } + + private void debugln(String in) { + debug(in + "\n"); + } + + private void debug(String mode, int x, int z, String in) { + debug("REGION " + mode + " " + fileName.getName() + "[" + x + "," + z + "] = " + in); + } + + private void debug(String mode, int x, int z, int count, String in) { + debug("REGION " + mode + " " + fileName.getName() + "[" + x + "," + z + "] " + count + "B = " + in); + } + + private void debugln(String mode, int x, int z, String in) { + debug(mode, x, z, in + "\n"); + } + + /* + * gets an (uncompressed) stream representing the chunk data returns null if + * the chunk is not found or an error occurs + */ + public synchronized DataInputStream getChunkDataInputStream(int x, int z) { + if (outOfBounds(x, z)) { + debugln("READ", x, z, "out of bounds"); + return null; + } + + try { + int offset = getOffset(x, z); + if (offset == 0) { + // debugln("READ", x, z, "miss"); + return null; + } + + int sectorNumber = offset >> 8; + int numSectors = offset & 0xFF; + + if (sectorNumber + numSectors > sectorFree.size()) { + debugln("READ", x, z, "invalid sector"); + return null; + } + + file.seek(sectorNumber * SECTOR_BYTES); + int length = file.readInt(); + + if (length > SECTOR_BYTES * numSectors) { + debugln("READ", x, z, "invalid length: " + length + " > 4096 * " + numSectors); + return null; + } + + byte version = file.readByte(); + if (version == VERSION_GZIP) { + byte[] data = new byte[length - 1]; + file.read(data); + DataInputStream ret = new DataInputStream(new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(data)))); + // debug("READ", x, z, " = found"); + return ret; + } else if (version == VERSION_DEFLATE) { + byte[] data = new byte[length - 1]; + file.read(data); + DataInputStream ret = new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(data)))); + // debug("READ", x, z, " = found"); + return ret; + } + + debugln("READ", x, z, "unknown version " + version); + return null; + } catch (IOException e) { + debugln("READ", x, z, "exception"); + return null; + } + } + + public DataOutputStream getChunkDataOutputStream(int x, int z) { + if (outOfBounds(x, z)) return null; + + return new DataOutputStream(new DeflaterOutputStream(new ChunkBuffer(x, z))); + } + + /* + * lets chunk writing be multithreaded by not locking the whole file as a + * chunk is serializing -- only writes when serialization is over + */ + class ChunkBuffer extends ByteArrayOutputStream { + private int x, z; + + public ChunkBuffer(int x, int z) { + super(8096); // initialize to 8KB + this.x = x; + this.z = z; + } + + public void close() { + RegionFile.this.write(x, z, buf, count); + } + } + + /* write a chunk at (x,z) with length bytes of data to disk */ + protected synchronized void write(int x, int z, byte[] data, int length) { + try { + int offset = getOffset(x, z); + int sectorNumber = offset >> 8; + int sectorsAllocated = offset & 0xFF; + int sectorsNeeded = (length + CHUNK_HEADER_SIZE) / SECTOR_BYTES + 1; + + // maximum chunk size is 1MB + if (sectorsNeeded >= 256) { + return; + } + + if (sectorNumber != 0 && sectorsAllocated == sectorsNeeded) { + /* we can simply overwrite the old sectors */ + debug("SAVE", x, z, length, "rewrite"); + write(sectorNumber, data, length); + } else { + /* we need to allocate new sectors */ + + /* mark the sectors previously used for this chunk as free */ + for (int i = 0; i < sectorsAllocated; ++i) { + sectorFree.set(sectorNumber + i, true); + } + + /* scan for a free space large enough to store this chunk */ + int runStart = sectorFree.indexOf(true); + int runLength = 0; + if (runStart != -1) { + for (int i = runStart; i < sectorFree.size(); ++i) { + if (runLength != 0) { + if (sectorFree.get(i)) runLength++; + else runLength = 0; + } else if (sectorFree.get(i)) { + runStart = i; + runLength = 1; + } + if (runLength >= sectorsNeeded) { + break; + } + } + } + + if (runLength >= sectorsNeeded) { + /* we found a free space large enough */ + debug("SAVE", x, z, length, "reuse"); + sectorNumber = runStart; + setOffset(x, z, (sectorNumber << 8) | sectorsNeeded); + for (int i = 0; i < sectorsNeeded; ++i) { + sectorFree.set(sectorNumber + i, false); + } + write(sectorNumber, data, length); + } else { + /* + * no free space large enough found -- we need to grow the + * file + */ + debug("SAVE", x, z, length, "grow"); + file.seek(file.length()); + sectorNumber = sectorFree.size(); + for (int i = 0; i < sectorsNeeded; ++i) { + file.write(emptySector); + sectorFree.add(false); + } + sizeDelta += SECTOR_BYTES * sectorsNeeded; + + write(sectorNumber, data, length); + setOffset(x, z, (sectorNumber << 8) | sectorsNeeded); + } + } + setTimestamp(x, z, (int) (System.currentTimeMillis() / 1000L)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /* write a chunk data to the region file at specified sector number */ + private void write(int sectorNumber, byte[] data, int length) throws IOException { + debugln(" " + sectorNumber); + file.seek(sectorNumber * SECTOR_BYTES); + file.writeInt(length + 1); // chunk length + file.writeByte(VERSION_DEFLATE); // chunk version number + file.write(data, 0, length); // chunk data + } + + /* is this an invalid chunk coordinate? */ + private boolean outOfBounds(int x, int z) { + return x < 0 || x >= 32 || z < 0 || z >= 32; + } + + private int getOffset(int x, int z) { + return offsets[x + z * 32]; + } + + public boolean hasChunk(int x, int z) { + return getOffset(x, z) != 0; + } + + private void setOffset(int x, int z, int offset) throws IOException { + offsets[x + z * 32] = offset; + file.seek((x + z * 32) * 4); + file.writeInt(offset); + } + + private void setTimestamp(int x, int z, int value) throws IOException { + chunkTimestamps[x + z * 32] = value; + file.seek(SECTOR_BYTES + (x + z * 32) * 4); + file.writeInt(value); + } + + public void close() throws IOException { + file.close(); + } +} \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/World.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/World.java new file mode 100644 index 00000000..a8dbe039 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/World.java @@ -0,0 +1,238 @@ +package codemetropolis.toolchain.rendering.control; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.util.LinkedList; +import java.util.Map; + +public class World { + + public final String PATH; + public final String NAME; + public final int GROUNDLEVEL; + public final boolean HASMOB; + public final int BIOMEID; + private boolean groundBuilding = true; + private int maxLoadedRegions = 1; + private int mobCounter = 0; + public final long mobLimit = 300; + private LinkedList loadedRegions = new LinkedList(); + + public World(String path, int groundLevel, byte id, boolean hasMob) { + + this.PATH = path; + this.GROUNDLEVEL = groundLevel; + this.BIOMEID = id; + this.HASMOB = hasMob; + String[] splitPath = path.split("[/\\\\]"); + this.NAME = splitPath[splitPath.length - 1]; + Level level = new Level(this); + level.writeToFile(); + } + + private void setBlock(int x, int y, int z, String blockId, NBTTag[] blockProperties, Object other) { + if (y < 0 || y > 255) { + throw new IllegalArgumentException("Block's 'y' coordinate must be between 0 and 255"); + } + + int regionX = x >> 9; + int regionZ = z >> 9; + int chunkX = x >> 4; + int chunkZ = z >> 4; + int chunkIndexX = (x % 512) >> 4; + int chunkIndexZ = (z % 512) >> 4; + chunkIndexX = chunkIndexX < 0 ? chunkIndexX + 32 : chunkIndexX; + chunkIndexZ = chunkIndexZ < 0 ? chunkIndexZ + 32 : chunkIndexZ; + int blockX = (x % 512) % 16; + int blockZ = (z % 512) % 16; + blockX = x < 0 ? blockX + 15 : blockX; + blockZ = z < 0 ? blockZ + 15 : blockZ; + + Region region = getRegion(regionX, regionZ); + Chunk chunk = region.getChunk(chunkIndexX, chunkIndexZ); + if(chunk == null) { + chunk = new Chunk(chunkX, chunkZ); + if(groundBuilding) + chunk.fill(GROUNDLEVEL, "minecraft:grass_block", new NBTTag[] {new NBTTag(NBTTag.Type.TAG_String, "snowy", "false"), NBTTag.END_TAG}); + region.setChunk(chunkIndexX, chunkIndexZ, chunk); + } + chunk.setBlock(blockX, y, blockZ, blockId, blockProperties); + + if( "minecraft:sign".equals(blockId) || "minecraft:wall_sign".equals(blockId) ) { + chunk.setSignText(x, y, z, (String) other); + } else if ( "minecraft:chest".equals(blockId) ) { + chunk.clearChestItems(x, y, z); + int[] items = (int[])other; + for(int i = 0; i < items.length; i += 2) + chunk.addChestItem(x, y, z, items[i], items[i+1]); + } else if ( "minecraft:standing_banner".equals(blockId) ) { + chunk.setBannerColor(x, y, z, (int)other); + } else if ( "minecraft:spawner".equals(blockId) ) { + chunk.setSpawner(x, y, z); + } else { + chunk.clearTileEntitiesAt(x, y, z); + } + + if(HASMOB && "minecraft:pig_place".equals(blockId) && mobCounter < mobLimit){ + chunk.setMob(x, y, z, "minecraft:pig"); + mobCounter++; + } + + } + + public void setBlock(int x, int y, int z, String blockId, NBTTag[] blockProperties) { + setBlock(x, y, z, blockId, blockProperties, null); + } + + public void setBlock(int x, int y, int z, String blockId) { + setBlock(x, y, z, blockId, new NBTTag[0], null); + } + + public void removeBlock(int x, int y, int z) { + setBlock(x, y, z, "minecraft:air"); + } + + public void setSignPost(int x, int y, int z, NBTTag[] blockProperties, String text) { + setBlock(x, y, z, "minecraft:sign", blockProperties, text); + } + + public void setSignPost(int x, int y, int z, String text) { + setSignPost(x, y, z, new NBTTag[] {new NBTTag(NBTTag.Type.TAG_String, "rotation", "0"), new NBTTag(NBTTag.Type.TAG_String, "waterlogged", "false"), new NBTTag(NBTTag.Type.TAG_End, null, null)}, text); + } + + public void setWallSign(int x, int y, int z, NBTTag[] blockProperties, String text) { + setBlock(x, y, z, "minecraft:wall_sign", blockProperties, text); + } + + public void setWallSign(int x, int y, int z, String text) { + setWallSign(x, y, z, new NBTTag[] {new NBTTag(NBTTag.Type.TAG_String, "facing", "north"), new NBTTag(NBTTag.Type.TAG_String, "waterlogged", "false"), new NBTTag(NBTTag.Type.TAG_End, null, null)}, text); + } + + public void setChest(int x, int y, int z, NBTTag[] blockProperties, int[] items) { + setBlock(x, y, z, "minecraft:chest", blockProperties, items); + } + + public void setChest(int x, int y, int z, int[] items) { + setChest(x, y, z, new NBTTag[] {new NBTTag(NBTTag.Type.TAG_String, "facing", "north"), new NBTTag(NBTTag.Type.TAG_String, "single", "single"), new NBTTag(NBTTag.Type.TAG_String, "waterlogged", "false"), new NBTTag(NBTTag.Type.TAG_End, null, null)}, items); + } + + public void setMob(int x, int y, int z, String name){ + setBlock(x, y, z, "minecraft:pig_place", new NBTTag[] {new NBTTag(NBTTag.Type.TAG_String, "", "")}, name); + } + + public void setBanner(int x, int y, int z, NBTTag[] blockProperties, BannerColor color) { + setBlock(x, y, z, "minecraft:standing_banner", blockProperties, color.ordinal()); + } + + public void setBlock(int x, int y, int z, String blockId, Map properties) { + setBlock(x, y, z, blockId, Chunk.PropertiesToTags(properties)); + } + + public void setSignPost(int x, int y, int z, Map properties, String text) { + setSignPost(x, y, z, Chunk.PropertiesToTags(properties), text); + } + + public void setWallSign(int x, int y, int z, Map properties, String text) { + setWallSign(x, y, z, Chunk.PropertiesToTags(properties), text); + } + + public void setBanner(int x, int y, int z, Map properties, BannerColor color) { + setBanner(x, y, z, Chunk.PropertiesToTags(properties), color); + } + + private Region getRegion(int x, int z) { + + for(Region r : loadedRegions) { + if(r.getX() == x && r.getZ() == z) { + return r; + } + } + + if(loadedRegions.size() >= maxLoadedRegions) { + loadedRegions.removeFirst().writeToFile(); + } + + Region result = Region.loadFromFile(x, z, this); + loadedRegions.add(result); + return result; + } + + public void groundBuildingOn() { + this.groundBuilding = true; + } + + public void groundBuildingOff() { + this.groundBuilding = false; + } + + public void setMaximumNumberOfLoadedRegions(int max) { + this.maxLoadedRegions = max; + } + + public void finish() { + for(Region r : loadedRegions) { + setBiomeForRegion(r); + r.writeToFile(); + } + loadedRegions.clear(); + } + + public void setBiomeForRegion(Region r){ + for(Chunk c : r.chunks){ + if(c != null){ + c.setBiome(BIOMEID); + } + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + File regionDirectory = new File(PATH + "/region"); + for(File f : regionDirectory.listFiles()) { + if(f.getName().matches("r\\.-?[0-9]*\\.-?[0-9]*.mca")) { + String[] parts = f.getName().split("\\."); + Region region = getRegion(Integer.parseInt(parts[1]), Integer.parseInt(parts[2])); + sb.append("** RegionFile: " + f.getName() + " **\n"); + sb.append(region.toString()); + sb.append("\n"); + } + } + return sb.toString(); + } + + public void toNBTFile(String path) { + try { + PrintWriter writer = new PrintWriter(new File(path + ".nbt")); + writer.println(this); + writer.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + public void toNBTFile() { + toNBTFile(NAME); + } + + public enum BannerColor { + BLACK, + RED, + GREEN, + BROWN, + BLUE, + PURPLE, + TURQUOISE, + LIGHT_GRAY, + GRAY, + PINK, + LIGHT_GREEN, + YELLOW, + LIGHT_BLUE, + LIGHT_PURPLE, + ORANGE, + WHITE; + } + +} \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/WorldBuilder.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/WorldBuilder.java index c8b174c2..8eb1bc51 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/WorldBuilder.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/control/WorldBuilder.java @@ -7,37 +7,83 @@ import java.util.ArrayList; import java.util.EventListener; import java.util.List; - +import codemetropolis.toolchain.rendering.model.building.Number; +import codemetropolis.toolchain.rendering.model.primitive.SignPost; import org.apache.commons.lang3.time.StopWatch; - -import codemetropolis.blockmodifier.World; import codemetropolis.toolchain.commons.cmxml.Buildable; import codemetropolis.toolchain.commons.cmxml.BuildableTree; import codemetropolis.toolchain.commons.cmxml.exceptions.CmxmlReaderException; import codemetropolis.toolchain.rendering.events.ProgressEvent; import codemetropolis.toolchain.rendering.events.ProgressEventListener; -import codemetropolis.toolchain.rendering.exceptions.BuildingTypeMismatchException; import codemetropolis.toolchain.rendering.exceptions.RenderingException; import codemetropolis.toolchain.rendering.exceptions.TooLongRenderDurationException; -import codemetropolis.toolchain.rendering.model.building.*; +import codemetropolis.toolchain.rendering.model.building.Bridge; +import codemetropolis.toolchain.rendering.model.building.Building; +import codemetropolis.toolchain.rendering.model.building.Cellar; +import codemetropolis.toolchain.rendering.model.building.Floor; +import codemetropolis.toolchain.rendering.model.building.Garden; +import codemetropolis.toolchain.rendering.model.building.Ground; +import codemetropolis.toolchain.rendering.model.building.Tunnel; import codemetropolis.toolchain.rendering.model.primitive.Boxel; public class WorldBuilder { - - private static final int GROUND_LEVEL = 60; + + public static final int GROUND_LEVEL = 60; + public static final int MIN_HEIGHT = 10; + public static final int MAX_HEIGHT = 200; + public static int TUNNEL_LEVEL = GROUND_LEVEL; + public static int BRIDGE_LEVEL = GROUND_LEVEL; private World world; private List buildings = new ArrayList(); + //private List numberList = new ArrayList(); private StopWatch stopWatch = new StopWatch(); private int count = 0; private int total = 0; - public WorldBuilder(String worldPath) { - world = new World(worldPath, GROUND_LEVEL); + public WorldBuilder(String worldPath, String inputPath) { + BuildableTree buildables = new BuildableTree(); + try { + buildables.loadFromFile(inputPath); + } catch (CmxmlReaderException e) { + e.printStackTrace(); + return; + } + + //List grounds = new ArrayList(); + int biomeID=1; + boolean hasMob = false; + for(Buildable b : buildables.getBuildables()) { + switch (b.getType()) { + case GROUND: + if (b.hasAttribute("biome-id")) { + if(Integer.parseInt(b.getAttributeValue("biome-id"))>-1 && Integer.parseInt(b.getAttributeValue("biome-id"))<40){ + biomeID = Integer.parseInt(b.getAttributeValue("biome-id")); + }else{ + try { + throw new NBTException("Biome ID must be between 0 and 39"); + } catch (NBTException e) { + e.printStackTrace(); + } + } + } + break; + case GARDEN: + if(b.hasAttribute("pig")){ + hasMob = true; + } + break; + default: + break; + } + + + } + world = new World(worldPath, GROUND_LEVEL, (byte)biomeID, hasMob); } - public void createBuildings(String inputPath) throws BuildingTypeMismatchException{ + public void createBuildings(String inputPath) throws Exception{ BuildableTree buildables = new BuildableTree(); try { buildables.loadFromFile(inputPath); @@ -45,15 +91,47 @@ public void createBuildings(String inputPath) throws BuildingTypeMismatchExcepti e.printStackTrace(); return; } - + calculateMaxDepthAndHeight(buildables); List floors = new ArrayList(); + List numbers= new ArrayList(); List cellars = new ArrayList(); List gardens = new ArrayList(); List grounds = new ArrayList(); + List tunnels = new ArrayList(); + List bridges = new ArrayList(); + + for(Buildable buildable: buildables.getBuildables() ){ + + if(buildable.getType()== Buildable.Type.GARDEN) { + for (Buildable b : buildable.getDescendants()) { + if(b.getType()== Buildable.Type.FLOOR){ + + buildable.setBuiltMetric1(buildable.getBuiltMetric1() + Integer.parseInt(b.getAttributeValue("BuiltMetric1"))); + buildable.setBuiltMetric2(buildable.getBuiltMetric2() + Integer.parseInt(b.getAttributeValue("BuiltMetric2"))); + buildable.setBuiltMetric3(buildable.getBuiltMetric3() + Integer.parseInt(b.getAttributeValue("BuiltMetric3"))); + }} + /* + Number First=new Number(buildable, "BuiltMetric1"); + Number Second=new Number(buildable, "BuiltMetric2"); + Number Third=new Number(buildable, "BuiltMetric3"); + + + First.getPrimitives().add(new WallSign(First.getPosition().getX()-1,First.getPosition().getY(), First.getPosition().getZ()+2, WallSign.Orientation.WEST, "First metric")); + Second.getPrimitives().add(new WallSign(Second.getPosition().getX()-1, Second.getPosition().getY(),Second.getPosition().getZ()+2 , WallSign.Orientation.WEST, "Second metric")); + Third.getPrimitives().add(new WallSign(Third.getPosition().getX()-1, Third.getPosition().getY(), Third.getPosition().getZ()+2, WallSign.Orientation.WEST, "Third metric")); + + numbers.add(First); + numbers.add(Second); + numbers.add(Third); +*/ + } + + + } for(Buildable b : buildables.getBuildables()) { switch(b.getType()) { - case FLOOR: + case FLOOR: Floor floor = new Floor(b); floors.add(floor); total += floor.getNumberOfBlocks(); @@ -75,14 +153,55 @@ public void createBuildings(String inputPath) throws BuildingTypeMismatchExcepti break; case CONTAINER: break; + case TUNNEL: + Tunnel tunnel = new Tunnel(b); + tunnels.add(tunnel); + break; + case BRIDGE: + Bridge bridge = new Bridge(b); + bridges.add(bridge); + break; } } + + for(Garden garden : gardens) { + for(Buildable b: garden.getInnerBuildable().getChildren() ){ + + if(b.getType()== Buildable.Type.FLOOR) { + + garden.setBuiltMetric1(garden.getBuiltMetric1() + Integer.parseInt(b.getAttributeValue("BuiltMetric1"))); + garden.setBuiltMetric2(garden.getBuiltMetric2() + Integer.parseInt(b.getAttributeValue("BuiltMetric2"))); + garden.setBuiltMetric3(garden.getBuiltMetric3() + Integer.parseInt(b.getAttributeValue("BuiltMetric3"))); + } + + + } + + + garden.getPrimitives().add(new SignPost(garden.getPosition().getX() + garden.getSize().getX() - 1, garden.getPosition().getY()+2, (garden.getPosition().getZ())-1+ garden.getSize().getZ() - 1, SignPost.Orientation.SOUTHEAST, "BuiltMetric1: " + Integer.toString(garden.getBuiltMetric1()))); + garden.getPrimitives().add(new SignPost(garden.getPosition().getX() + garden.getSize().getX() - 1, garden.getPosition().getY()+2, (garden.getPosition().getZ())-2 + garden.getSize().getZ() - 1, SignPost.Orientation.SOUTHEAST, "BuiltMetric2: " + Integer.toString(garden.getBuiltMetric2()))); + garden.getPrimitives().add(new SignPost(garden.getPosition().getX() + garden.getSize().getX() - 1, garden.getPosition().getY()+2, (garden.getPosition().getZ())-3 + garden.getSize().getZ() - 1, SignPost.Orientation.SOUTHEAST, "BuiltMetric3: " + Integer.toString(garden.getBuiltMetric3()))); + + } buildings.addAll(grounds); buildings.addAll(gardens); + buildings.addAll(numbers); buildings.addAll(cellars); buildings.addAll(floors); + for(Tunnel t : tunnels) { + t.prepareStairs(); + total += t.getNumberOfBlocks(); + } + buildings.addAll(tunnels); + + for(Bridge b : bridges) { + b.prepareStairs(); + total += b.getNumberOfBlocks(); + } + buildings.addAll(bridges); + raiseProgressEvent(BuildPhase.READING_INPUT_FILE, 1, 1, -1); } @@ -166,4 +285,19 @@ private synchronized void raiseProgressEvent(BuildPhase phase, long count, long } //endregion + + private void calculateMaxDepthAndHeight(BuildableTree buildables) { + for(Buildable b : buildables.getBuildables()) { + if(b.getType() == Buildable.Type.CELLAR && b.getPositionY() < TUNNEL_LEVEL) { + TUNNEL_LEVEL = b.getPositionY(); + continue; + } + if(b.getType() == Buildable.Type.FLOOR && b.getPositionY() > BRIDGE_LEVEL) { + BRIDGE_LEVEL = b.getPositionY(); + continue; + } + } + } + + } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/BasicBlock.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/BasicBlock.java index dc71b59d..637fa9f1 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/BasicBlock.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/BasicBlock.java @@ -1,90 +1,125 @@ package codemetropolis.toolchain.rendering.model; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.util.Collections; import java.util.HashMap; import java.util.Map; -import codemetropolis.toolchain.rendering.RenderingExecutor; - public class BasicBlock { - public static final BasicBlock NonBlock; - public static final Map idToName; - public static final Map idToHumanReadableName; - public static final Map nameToId; - public static final Map humanReadableNameToId; - - static { - NonBlock = new BasicBlock((short)-1 ); - idToName = new HashMap(); - idToHumanReadableName = new HashMap(); - nameToId = new HashMap(); - humanReadableNameToId = new HashMap(); - - InputStream csvStream = RenderingExecutor.class.getClassLoader().getResourceAsStream("blocks.csv"); - try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(csvStream, "UTF-8"))) { - String line; - while ((line = bufferedReader.readLine()) != null) { - String[] blockInfo = line.split(","); - idToName.put(Short.parseShort(blockInfo[0]), blockInfo[1]); - idToHumanReadableName.put(Short.parseShort(blockInfo[0]), blockInfo[2]); - nameToId.put(blockInfo[1], Short.parseShort(blockInfo[0])); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - private short id; - private int data; - - public BasicBlock(short id) { - this(id, 0); - } + public static final BasicBlock NON_BLOCK = new BasicBlock(""); + public static final BasicBlock Mob = new BasicBlock("minecraft:pig_place"); + + // Blocks + public static final BasicBlock AIR = new BasicBlock("minecraft:air"); + public static final BasicBlock STONE = new BasicBlock("minecraft:stone"); + public static final BasicBlock DIRT = new BasicBlock("minecraft:dirt"); + public static final BasicBlock NETHERRACK = new BasicBlock("minecraft:netherrack"); + public static final BasicBlock IRONBAR = new BasicBlock("minecraft:iron_bars"); + public static final BasicBlock FIRE = new BasicBlock("minecraft:fire"); + public static final BasicBlock STONE_BRICKS = new BasicBlock("minecraft:stone_bricks"); + public static final BasicBlock IRON_BLOCK = new BasicBlock("minecraft:iron_block"); + public static final BasicBlock GLASS = new BasicBlock("minecraft:glass"); + public static final BasicBlock LOG = new BasicBlock("minecraft:oak_log"); + public static final BasicBlock COBBLESTONE = new BasicBlock("minecraft:cobblestone"); + public static final BasicBlock OBSIDIAN = new BasicBlock("minecraft:obsidian"); + public static final BasicBlock SAND = new BasicBlock("minecraft:cut_sandstone"); + public static final BasicBlock ORIGINAL_SAND = new BasicBlock("minecraft:sand"); + public static final BasicBlock PLANKS = new BasicBlock("minecraft:oak_planks"); + public static final BasicBlock SANDSTONE = new BasicBlock("minecraft:sandstone"); + public static final BasicBlock GRASS_BLOCK = new BasicBlock("minecraft:grass_block"); + public static final BasicBlock REDSTONE_BLOCK = new BasicBlock("minecraft:redstone_block"); + public static final BasicBlock BEDROCK = new BasicBlock("minecraft:bedrock"); + public static final BasicBlock LAPIS = new BasicBlock("minecraft:lapis_block"); + public static final BasicBlock BLUEGLASS = new BasicBlock("minecraft:blue_stained_glass"); + public static final BasicBlock WHITEGLASS = new BasicBlock("minecraft:white_stained_glass"); + public static final BasicBlock GOLDBLOCK = new BasicBlock("minecraft:gold_block"); + public static final BasicBlock EMERALDBLOCK = new BasicBlock("minecraft:emerald_block"); + public static final BasicBlock BRICKS = new BasicBlock("minecraft:bricks"); + public static final BasicBlock NETHERBRICKS = new BasicBlock("minecraft:nether_bricks"); + public static final BasicBlock GRASS_PATH = new BasicBlock("minecraft:grass_path"); + public static final BasicBlock COBBLESTONE_WALL = new BasicBlock("minecraft:cobblestone_wall"); + public static final BasicBlock REDSTONE_LAMP = new BasicBlock("minecraft:redstone_lamp", + new HashMap() { + { + put("lit", "true"); + } + }); + public static final BasicBlock BRICKSTAIRS_NORTH = new BasicBlock("minecraft:brick_stairs", + new HashMap() { + { + put("facing", "north"); + } + }); + public static final BasicBlock BRICKSTAIRS_SOUTH = new BasicBlock("minecraft:brick_stairs", + new HashMap() { + { + put("facing", "south"); + } + }); - public BasicBlock(short id, int data) { + // Items + public static final BasicBlock FENCE = new BasicBlock("minecraft:oak_fence"); + public static final BasicBlock ACACIA_FENCE = new BasicBlock("minecraft:acacia_fence"); + public static final BasicBlock TORCH = new BasicBlock("minecraft:wall_torch"); + public static final BasicBlock BANNER = new BasicBlock("minecraft:white_banner"); + public static final BasicBlock DOOR = new BasicBlock("minecraft:oak_door"); + public static final BasicBlock SIGN = new BasicBlock("minecraft:sign"); + public static final BasicBlock WALL_SIGN = new BasicBlock("minecraft:wall_sign"); + + // Plants + public static final BasicBlock POPPY = new BasicBlock("minecraft:poppy"); + public static final BasicBlock DANDELION = new BasicBlock("minecraft:dandelion"); + public static final BasicBlock BROWN_MUSHROOM = new BasicBlock("minecraft:brown_mushroom"); + public static final BasicBlock OAK_SAPLING = new BasicBlock("minecraft:oak_sapling"); + + // Wools + public static final BasicBlock RED_WOOL = new BasicBlock("minecraft:red_wool"); + public static final BasicBlock GREENWOOL = new BasicBlock("minecraft:lime_wool"); + public static final BasicBlock BLUE_WOOL = new BasicBlock("minecraft:light_blue_wool"); + public static final BasicBlock YELLOW_WOOL = new BasicBlock("minecraft:yellow_wool"); + public static final BasicBlock MAGENTA_WOOL = new BasicBlock("minecraft:magenta_wool"); + public static final BasicBlock PURPLE_WOOL = new BasicBlock("minecraft:purple_wool"); + public static final BasicBlock BLACK_WOOL = new BasicBlock("minecraft:black_wool"); + public static final BasicBlock GRAY_WOOL = new BasicBlock("minecraft:gray_wool"); + public static final BasicBlock LIGHT_GRAY_WOOL = new BasicBlock("minecraft:light_gray_wool"); + public static final BasicBlock ORANGE_WOOL = new BasicBlock("minecraft:orange_gray_wool"); + public static final BasicBlock WHITE_WOOL = new BasicBlock("minecraft:white_gray_wool"); + public static final BasicBlock PINK_WOOL = new BasicBlock("minecraft:pink_gray_wool"); + private String id; + private Map properties = Collections.emptyMap(); + + public BasicBlock(String id) { this.id = id; - this.data = data; - } - - public BasicBlock(String name) { - this(nameToId.get(name), 0); } - - public BasicBlock(String name, int data) { - this(nameToId.get(name), data); + + public BasicBlock(String id, Map properties) { + this.id = id; + this.properties = properties; } - + public BasicBlock(BasicBlock original) { this.id = original.id; - this.data = original.data; + this.properties = new HashMap<>(original.properties); } - - public String getName() { - return idToName.get(id); + + public Map getProperties() { + return properties; } - - public String getHumanReadableName() { - return idToHumanReadableName.get(id); + + public void setProperties(Map properties) { + this.properties = properties; } - public short getId() { + public String getId() { return id; } - public int getData() { - return data; - } - @Override public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + data; - result = prime * result + id; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((properties == null) ? 0 : properties.hashCode()); return result; } @@ -97,16 +132,22 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; BasicBlock other = (BasicBlock) obj; - if (data != other.data) + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) return false; - if (id != other.id) + if (properties == null) { + if (other.properties != null) + return false; + } else if (!properties.equals(other.properties)) return false; return true; } @Override public String toString() { - return getHumanReadableName() + (data != 0 ? data : ""); + return "BasicBlock [id=" + id + ", properties=" + properties + "]"; } - + } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Bridge.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Bridge.java new file mode 100644 index 00000000..c445fd98 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Bridge.java @@ -0,0 +1,61 @@ +package codemetropolis.toolchain.rendering.model.building; + +import codemetropolis.toolchain.commons.cmxml.Buildable; +import codemetropolis.toolchain.commons.cmxml.Buildable.Type; +import codemetropolis.toolchain.commons.cmxml.Point; +import codemetropolis.toolchain.rendering.control.WorldBuilder; +import codemetropolis.toolchain.rendering.exceptions.BuildingTypeMismatchException; +import codemetropolis.toolchain.rendering.exceptions.RenderingException; +import codemetropolis.toolchain.rendering.model.BasicBlock; + +public class Bridge extends Linking { + + public Bridge(Buildable innerBuildable) throws RenderingException { + + super(innerBuildable); + + if ( innerBuildable.getType() != Type.BRIDGE ) { + throw new BuildingTypeMismatchException(innerBuildable.getType(), getClass()); + } + + this.width = 4; + this.height = 2; + + this.level = WorldBuilder.MAX_HEIGHT; + + prepareLinking(new BasicBlock[][][] { { { BasicBlock.STONE } } }); + } + + public int calculateHeight(Buildable buildable) { + + return level - WorldBuilder.GROUND_LEVEL; + } + + public Point calculateStepPosition(boolean isTarget) { + Point stepPosition; + + if(!isTarget) { + if ("NORTH".equals(this.orientation)) { + stepPosition = new Point(position.getX(), WorldBuilder.GROUND_LEVEL, position.getZ() + size.getZ() - adjustSize(this.width, MIN_SIZE)); + } else if ("SOUTH".equals(this.orientation)) { + stepPosition = new Point(position.getX(), WorldBuilder.GROUND_LEVEL, position.getZ()); + } else if ("WEST".equals(this.orientation)) { + stepPosition = new Point(position.getX() + size.getX() - adjustSize(this.width, MIN_SIZE), WorldBuilder.GROUND_LEVEL, position.getZ()); + } else { + stepPosition = new Point(position.getX(), WorldBuilder.GROUND_LEVEL, position.getZ()); + } + } else { + if ("NORTH".equals(this.orientation)) { + stepPosition = new Point(position.getX(), WorldBuilder.GROUND_LEVEL, position.getZ()); + } else if ("SOUTH".equals(this.orientation)) { + stepPosition = new Point(position.getX(), WorldBuilder.GROUND_LEVEL, position.getZ() + size.getZ() - adjustSize(this.width, MIN_SIZE)); + } else if ("WEST".equals(this.orientation)) { + stepPosition = new Point(position.getX(), WorldBuilder.GROUND_LEVEL, position.getZ()); + } else { + stepPosition = new Point(position.getX()+ size.getX() - adjustSize(this.width, MIN_SIZE), WorldBuilder.GROUND_LEVEL, position.getZ()); + } + } + + return stepPosition; + } +} diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Building.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Building.java index 87e2f213..0b75e3ea 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Building.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Building.java @@ -15,49 +15,65 @@ public class Building { protected LinkedList primitives = new LinkedList(); protected LinkedList signs = new LinkedList(); protected Buildable innerBuildable; - + protected Point position; protected Point center; protected Point size; - - public Building( Buildable innerBuildable ) - { + + protected int BuiltMetric1 , BuiltMetric2 , BuiltMetric3; + + public Building(Buildable innerBuildable) { this.innerBuildable = innerBuildable; - - size = new Point( - adjustSize(innerBuildable.getSizeX()), - adjustSize(innerBuildable.getSizeY()), - adjustSize(innerBuildable.getSizeZ()) - ); - - position = new Point( - innerBuildable.getPositionX(), - innerBuildable.getPositionY(), - innerBuildable.getPositionZ() - ); - - center = new Point( - (int)(size.getX() * 0.5), - (int)(size.getY() * 0.5), - (int)(size.getZ() * 0.5) - ); + + size = new Point(adjustSize(innerBuildable.getSizeX(), MIN_SIZE), + adjustSize(innerBuildable.getSizeY(), MIN_SIZE), + adjustSize(innerBuildable.getSizeZ(), MIN_SIZE)); + if (innerBuildable.getType() == Buildable.Type.FLOOR) { + BuiltMetric1 = Integer.parseInt(this.innerBuildable.getAttributeValue("BuiltMetric1")); + BuiltMetric2 = Integer.parseInt(this.innerBuildable.getAttributeValue("BuiltMetric2")); + BuiltMetric3 = Integer.parseInt(this.innerBuildable.getAttributeValue("BuiltMetric3")); + + + } else{ + BuiltMetric1 = 0; + BuiltMetric2 = 0; + BuiltMetric3 = 0; } - - private static int adjustSize( int x ) { - if(x < MIN_SIZE) return MIN_SIZE; - if(x % 2 == 0) return x + 1; + + position = new Point(innerBuildable.getPositionX(), innerBuildable.getPositionY(), + innerBuildable.getPositionZ()); + + center = new Point((int) (size.getX() * 0.5), (int) (size.getY() * 0.5), (int) (size.getZ() * 0.5)); + } + + public Building() {} + + public void setPosition(Point position) { + this.position = position; + } + + public void setSize(Point size) { + this.size = size; + } + + protected static int adjustSize( int x, int min_size ) { + if(x < min_size) return min_size; + if (x % 2 == 0) + return x + 1; return x; } + + public int toCSVFile(File directory) { int count = 0; - for(Primitive primitive : primitives) { + for (Primitive primitive : primitives) { primitive.toCSVFile(directory); count += primitive.getNumberOfBlocks(); } return count; } - + public Buildable getInnerBuildable() { return innerBuildable; } @@ -73,12 +89,39 @@ public Point getCenter() { public Point getSize() { return size; } + public int getBuiltMetric1() { + return BuiltMetric1; + } + + public void setBuiltMetric1(int builtMetric1) { + BuiltMetric1 = builtMetric1; + } + + public int getBuiltMetric2() { + return BuiltMetric2; + } + + public void setBuiltMetric2(int builtMetric2) { + BuiltMetric2 = builtMetric2; + } + + public int getBuiltMetric3() { + return BuiltMetric3; + } + public void setBuiltMetric3(int builtMetric3) { + BuiltMetric3 = builtMetric3; + } + public int getNumberOfBlocks() { int result = 0; - for(Primitive p : primitives) + for (Primitive p : primitives) result += p.getNumberOfBlocks(); return result; } - + + public LinkedList getPrimitives() { + return this.primitives; + } + } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Cellar.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Cellar.java index 1da38d20..0fa48a75 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Cellar.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Cellar.java @@ -1,38 +1,45 @@ package codemetropolis.toolchain.rendering.model.building; +import java.util.LinkedList; + import codemetropolis.toolchain.commons.cmxml.Buildable; import codemetropolis.toolchain.commons.cmxml.Buildable.Type; import codemetropolis.toolchain.commons.cmxml.Point; import codemetropolis.toolchain.rendering.exceptions.BuildingTypeMismatchException; import codemetropolis.toolchain.rendering.model.BasicBlock; import codemetropolis.toolchain.rendering.model.pattern.RepeationPattern; +import codemetropolis.toolchain.rendering.model.primitive.Primitive; import codemetropolis.toolchain.rendering.model.primitive.SolidBox; import codemetropolis.toolchain.rendering.util.Orientation; public class Cellar extends Floor { - public Cellar(Buildable innerBuildable) throws BuildingTypeMismatchException { + public Cellar(Buildable innerBuildable) throws Exception { super(innerBuildable); - - if ( innerBuildable.getType() != Type.CELLAR ) + + if (innerBuildable.getType() != Type.CELLAR) { throw new BuildingTypeMismatchException(innerBuildable.getType(), getClass()); - - primitives.add( - 0, - new SolidBox( - position.translate( new Point( 1, 1, 1 ) ), - size.translate( new Point( -2, -2, -2 ) ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air" ) } } } ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air" ) } } } ), - Orientation.NearX ) ); - - primitives.add( - new SolidBox( - position.translate( new Point( center.getX() - 3, size.getY() + 1, center.getZ() - 3 ) ), - new Point( 7, 1, 7 ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air" ) } } } ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air" ) } } } ), - Orientation.NearX ) ); + } + + primitives.addAll(makePrimitives()); + primitives.addAll(prepareStairs()); + primitives.addAll(prepareSigns()); + + } + + public LinkedList makePrimitives() { + LinkedList primitive = new LinkedList<>(); + + primitive.add(0, + new SolidBox(position.translate(new Point(1, 1, 1)), size.translate(new Point(-2, -2, -2)), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), Orientation.NearX)); + //nem ezek + primitive.add(new SolidBox(position.translate(new Point(center.getX() - 3, size.getY() + 1, center.getZ() - 3)), + new Point(7, 1, 7), new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), Orientation.NearX)); + + return primitive; } -} +} \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Floor.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Floor.java index ced4a538..e0f843d0 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Floor.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Floor.java @@ -1,344 +1,317 @@ package codemetropolis.toolchain.rendering.model.building; +import java.util.LinkedList; + import codemetropolis.toolchain.commons.cmxml.Buildable; import codemetropolis.toolchain.commons.cmxml.Buildable.Type; import codemetropolis.toolchain.commons.cmxml.Point; import codemetropolis.toolchain.rendering.exceptions.BuildingTypeMismatchException; import codemetropolis.toolchain.rendering.model.BasicBlock; +import codemetropolis.toolchain.rendering.model.pattern.Pattern; import codemetropolis.toolchain.rendering.model.pattern.RandomPattern; import codemetropolis.toolchain.rendering.model.pattern.RepeationPattern; import codemetropolis.toolchain.rendering.model.primitive.Door; import codemetropolis.toolchain.rendering.model.primitive.EmptyBox; +import codemetropolis.toolchain.rendering.model.primitive.Primitive; import codemetropolis.toolchain.rendering.model.primitive.Row; +import codemetropolis.toolchain.rendering.model.primitive.Row.BlockFacing; import codemetropolis.toolchain.rendering.model.primitive.SolidBox; import codemetropolis.toolchain.rendering.model.primitive.WallSign; -import codemetropolis.toolchain.rendering.util.Character; import codemetropolis.toolchain.rendering.util.Orientation; public class Floor extends Building { - public Floor(Buildable innerBuildable) throws BuildingTypeMismatchException { + public Floor(Buildable innerBuildable) throws Exception { super(innerBuildable); - - if ( innerBuildable.getType()!= Type.FLOOR && innerBuildable.getType() != Type.CELLAR ) + + if (innerBuildable.getType() != Type.FLOOR && innerBuildable.getType() != Type.CELLAR) throw new BuildingTypeMismatchException(innerBuildable.getType(), getClass()); + - prepareWalls(); - prepareStairs(); - prepareDoor(); - prepareSigns(); - prepareTorches(); - } - - protected void prepareDoor() { - BasicBlock _red = new BasicBlock( "minecraft:redstone_block" ); - BasicBlock _lgt = new BasicBlock( "minecraft:lit_redstone_lamp" ); - BasicBlock _rwl = new BasicBlock( "minecraft:wool", 14 ); - BasicBlock _gwl = new BasicBlock( "minecraft:wool", 5 ); - BasicBlock _bwl = new BasicBlock( "minecraft:wool", 3 ); - BasicBlock _ywl = new BasicBlock( "minecraft:wool", 4 ); - primitives.add( - new SolidBox( - position.translate( new Point( center.getX() - 1, 0, 0 ) ), new Point( 3, 4, 1 ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air", 2 ) } } } ), - new RepeationPattern( - new BasicBlock[][][] - { - { - { _rwl }, - { _lgt }, - { _red }, - { _rwl } - } - } ), - Orientation.NearX ) - ); - primitives.add( - new SolidBox( - position.translate( new Point( center.getX() - 1, 0, size.getZ() - 1 ) ), new Point( 3, 4, 1 ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air", 2 ) } } } ), - new RepeationPattern( - new BasicBlock[][][] - { - { - { _gwl }, - { _lgt }, - { _red }, - { _gwl } - } - } ), - Orientation.NearX ) - ); - primitives.add( - new SolidBox( - position.translate( new Point( 0, 0, center.getZ()-1 ) ), new Point( 1, 4, 3 ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air", 2 ) } } } ), - new RepeationPattern( - new BasicBlock[][][] - { - { - { _bwl }, - { _lgt }, - { _red }, - { _bwl } - } - } ), - Orientation.NearX ) - ); - primitives.add( - new SolidBox( - position.translate( new Point( size.getX()-1, 0, center.getZ() - 1 ) ), new Point( 1, 4, 3 ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air", 2 ) } } } ), - new RepeationPattern( - new BasicBlock[][][] - { - { - { _ywl }, - { _lgt }, - { _red }, - { _ywl } - } - } ), - Orientation.NearX ) - ); + primitives.addAll(prepareWalls()); + primitives.addAll(prepareDoor()); + primitives.addAll(prepareTorches()); + + if (innerBuildable.getType() == Type.FLOOR) { + primitives.addAll(prepareStairs()); + primitives.addAll(prepareSigns()); + + } + - primitives.add(new Door(position.getX() + size.getX() / 2, position.getY() + 1, position.getZ(), Door.Orientation.SOUTH)); - primitives.add(new Door(position.getX() + size.getX() / 2, position.getY() + 1, position.getZ() + size.getZ() - 1, Door.Orientation.NORTH)); - primitives.add(new Door(position.getX(), position.getY() + 1, position.getZ() + size.getZ() / 2, Door.Orientation.EAST)); - primitives.add(new Door(position.getX() + size.getX() - 1, position.getY() + 1, position.getZ() + size.getZ() / 2, Door.Orientation.WEST)); } - - protected void prepareStairs() { - BasicBlock _air = new BasicBlock( (short) 0 ); - BasicBlock _str = new BasicBlock( (short) 1 ); - BasicBlock _cre = new BasicBlock( (short) 85 ); - primitives.add( - new SolidBox( - position.translate( new Point( center.getX() - 2, 0, center.getZ() - 2 ) ), - new Point( 5, size.getY() + 1, 5 ), - new RepeationPattern( - new BasicBlock[][][] - { - { - { _air, _air, _air, _air, _air }, - { _air, _str, _air, _air, _air }, - { _air, _air, _cre, _air, _air }, - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _air, _air } - }, - { - { _air, _air, _air, _air, _air }, - { _air, _air, _str, _air, _air }, - { _air, _air, _cre, _air, _air }, - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _air, _air } - }, - { - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _str, _air }, - { _air, _air, _cre, _air, _air }, - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _air, _air } - }, - { - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _air, _air }, - { _air, _air, _cre, _str, _air }, - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _air, _air } - }, - { - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _air, _air }, - { _air, _air, _cre, _air, _air }, - { _air, _air, _air, _str, _air }, - { _air, _air, _air, _air, _air } - }, - { - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _air, _air }, - { _air, _air, _cre, _air, _air }, - { _air, _air, _str, _air, _air }, - { _air, _air, _air, _air, _air } - }, - { - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _air, _air }, - { _air, _air, _cre, _air, _air }, - { _air, _str, _air, _air, _air }, - { _air, _air, _air, _air, _air } - }, - { - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _air, _air }, - { _air, _str, _cre, _air, _air }, - { _air, _air, _air, _air, _air }, - { _air, _air, _air, _air, _air } - } - } ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:fence" ) } } } ), - Orientation.NearY ) ); + + protected LinkedList prepareDoor() { + LinkedList doors = new LinkedList<>(); + + doors.add(new SolidBox(position.translate(new Point(center.getX() - 1, 0, 0)), new Point(3, 4, 1), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.RED_WOOL }, { BasicBlock.REDSTONE_LAMP }, + { BasicBlock.REDSTONE_BLOCK }, { BasicBlock.RED_WOOL } } }), + Orientation.NearX)); + doors.add(new SolidBox(position.translate(new Point(center.getX() - 1, 0, size.getZ() - 1)), new Point(3, 4, 1), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.GREENWOOL }, { BasicBlock.REDSTONE_LAMP }, + { BasicBlock.REDSTONE_BLOCK }, { BasicBlock.GREENWOOL } } }), + Orientation.NearX)); + doors.add(new SolidBox(position.translate(new Point(0, 0, center.getZ() - 1)), new Point(1, 4, 3), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.BLUE_WOOL }, { BasicBlock.REDSTONE_LAMP }, + { BasicBlock.REDSTONE_BLOCK }, { BasicBlock.BLUE_WOOL } } }), + Orientation.NearX)); + doors.add(new SolidBox(position.translate(new Point(size.getX() - 1, 0, center.getZ() - 1)), new Point(1, 4, 3), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.YELLOW_WOOL }, { BasicBlock.REDSTONE_LAMP }, + { BasicBlock.REDSTONE_BLOCK }, { BasicBlock.YELLOW_WOOL } } }), + Orientation.NearX)); + + doors.add(new Door(position.getX() + size.getX() / 2, position.getY() + 1, position.getZ(), + Door.Orientation.SOUTH)); + doors.add(new Door(position.getX() + size.getX() / 2, position.getY() + 1, position.getZ() + size.getZ() - 1, + Door.Orientation.NORTH)); + doors.add(new Door(position.getX(), position.getY() + 1, position.getZ() + size.getZ() / 2, + Door.Orientation.EAST)); + doors.add(new Door(position.getX() + size.getX() - 1, position.getY() + 1, position.getZ() + size.getZ() / 2, + Door.Orientation.WEST)); + + return doors; } - protected void prepareWalls() { + protected Pattern getStairRepetationPattern() { + BasicBlock _air = BasicBlock.AIR; + BasicBlock _str = BasicBlock.STONE; + BasicBlock _cre = BasicBlock.FENCE; + + return new RepeationPattern(new BasicBlock[][][] { + { { _air, _air, _air, _air, _air }, { _air, _str, _air, _air, _air }, { _air, _air, _cre, _air, _air }, + { _air, _air, _air, _air, _air }, { _air, _air, _air, _air, _air } }, + { { _air, _air, _air, _air, _air }, { _air, _air, _str, _air, _air }, { _air, _air, _cre, _air, _air }, + { _air, _air, _air, _air, _air }, { _air, _air, _air, _air, _air } }, + { { _air, _air, _air, _air, _air }, { _air, _air, _air, _str, _air }, { _air, _air, _cre, _air, _air }, + { _air, _air, _air, _air, _air }, { _air, _air, _air, _air, _air } }, + { { _air, _air, _air, _air, _air }, { _air, _air, _air, _air, _air }, { _air, _air, _cre, _str, _air }, + { _air, _air, _air, _air, _air }, { _air, _air, _air, _air, _air } }, + { { _air, _air, _air, _air, _air }, { _air, _air, _air, _air, _air }, { _air, _air, _cre, _air, _air }, + { _air, _air, _air, _str, _air }, { _air, _air, _air, _air, _air } }, + { { _air, _air, _air, _air, _air }, { _air, _air, _air, _air, _air }, { _air, _air, _cre, _air, _air }, + { _air, _air, _str, _air, _air }, { _air, _air, _air, _air, _air } }, + { { _air, _air, _air, _air, _air }, { _air, _air, _air, _air, _air }, { _air, _air, _cre, _air, _air }, + { _air, _str, _air, _air, _air }, { _air, _air, _air, _air, _air } }, + { { _air, _air, _air, _air, _air }, { _air, _air, _air, _air, _air }, { _air, _str, _cre, _air, _air }, + { _air, _air, _air, _air, _air }, { _air, _air, _air, _air, _air } } }); + } + protected LinkedList prepareStairs() { + + LinkedList stairs = new LinkedList<>(); + + stairs.add(new SolidBox(position.translate(new Point(center.getX() - 2, 0, center.getZ() - 2)), + new Point(5, size.getY() + 1, 5), getStairRepetationPattern(), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.FENCE } } }), Orientation.NearY)); + return stairs; + } + + protected LinkedList prepareWalls() throws Exception { RepeationPattern _bottomFill; RepeationPattern _topFill; RandomPattern _sideFill; RepeationPattern _stroke; BasicBlock _sideBlock; BasicBlock _strcBlock; + BasicBlock block; + //BasicBlock block; + LinkedList walls = new LinkedList<>(); - if(innerBuildable.hasAttribute( "character" )) - { - Character character = Character.parse(innerBuildable.getAttributeValue("character")); - _sideBlock = character.getBlock(); - _topFill = new RepeationPattern( new BasicBlock[][][] { { { character.getTopBlock() } } } ); + if (innerBuildable.hasAttribute("character")) { + String character = innerBuildable.getAttributeValue("character"); + switch (character) { + case "glass": + _sideBlock = new BasicBlock(BasicBlock.GLASS); + _topFill = new RepeationPattern(new BasicBlock[][][] {{{BasicBlock.GLASS}}}); + break; + case "sand": + _sideBlock = new BasicBlock(BasicBlock.SAND); + _topFill = new RepeationPattern(new BasicBlock[][][] {{{BasicBlock.SAND}}}); + break; + case "planks": + _sideBlock = new BasicBlock(BasicBlock.PLANKS); + _topFill = new RepeationPattern(new BasicBlock[][][] {{{BasicBlock.PLANKS}}}); + break; + case "stone": + _sideBlock = new BasicBlock(BasicBlock.STONE); + _topFill = new RepeationPattern(new BasicBlock[][][] {{{BasicBlock.STONE}}}); + break; + case "obsidian": + _sideBlock = new BasicBlock(BasicBlock.OBSIDIAN); + _topFill = new RepeationPattern(new BasicBlock[][][] {{{BasicBlock.OBSIDIAN}}}); + break; + default: + _sideBlock = new BasicBlock(BasicBlock.MAGENTA_WOOL); + _topFill = new RepeationPattern(new BasicBlock[][][] {{{BasicBlock.MAGENTA_WOOL}}}); + break; + } } else { - _sideBlock = new BasicBlock( "minecraft:wool", 2 ); - _topFill = new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:wool", 2 ) } } } ); + _sideBlock = BasicBlock.MAGENTA_WOOL; + _topFill = new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.MAGENTA_WOOL } } }); + } - if(innerBuildable.hasAttribute( "external_character" )) - { - Character externalCharacter = Character.parse(innerBuildable.getAttributeValue("external_character")); - _bottomFill = new RepeationPattern( new BasicBlock[][][] { { { externalCharacter.getBlock() } } } ); - _strcBlock = externalCharacter.getBlock(); - _stroke = new RepeationPattern( new BasicBlock[][][] { { { externalCharacter.getBlock() } } } ); + if (innerBuildable.hasAttribute("external_character")) { + String externalCharacter = innerBuildable.getAttributeValue("external_character"); + + switch (externalCharacter) { + case "metal": + block = new BasicBlock(BasicBlock.IRON_BLOCK); + break; + case "sandstone": + block = new BasicBlock(BasicBlock.SANDSTONE); + break; + case "wood": + block = new BasicBlock(BasicBlock.LOG); + break; + case "cobblestone": + block = new BasicBlock(BasicBlock.COBBLESTONE); + break; + case "obsidian": + block = new BasicBlock(BasicBlock.OBSIDIAN); + break; + default: + block = new BasicBlock(BasicBlock.PURPLE_WOOL); + break; + } + _bottomFill = new RepeationPattern(new BasicBlock[][][] {{{block}}}); + _strcBlock = block; + _stroke = new RepeationPattern(new BasicBlock[][][] {{{block}}}); } else { - _bottomFill = new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:wool", 2 ) } } } ); - _strcBlock = new BasicBlock( "minecraft:wool", 10 ); - _stroke = new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:wool", 15 ) } } } ); + _bottomFill = new RepeationPattern(new BasicBlock[][][] {{{BasicBlock.MAGENTA_WOOL}}}); + _strcBlock = BasicBlock.PURPLE_WOOL; + _stroke = new RepeationPattern(new BasicBlock[][][] {{{BasicBlock.BLACK_WOOL}}}); + _topFill = new RepeationPattern(new BasicBlock[][][] {{{BasicBlock.MAGENTA_WOOL}}}); } - - RandomPattern _fallbackPattern = new RandomPattern( new RepeationPattern( new BasicBlock[][][] { { { BasicBlock.NonBlock } } } ) ); - _fallbackPattern.add( new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:fence" ) } } } ), .5 ); - _sideFill = new RandomPattern( _fallbackPattern ); + RandomPattern _fallbackPattern = new RandomPattern( + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.NON_BLOCK } } })); + _fallbackPattern.add(new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.FENCE } } }), .5); + _sideFill = new RandomPattern(_fallbackPattern); _sideFill.add( - new RepeationPattern( - new BasicBlock[][][] - { - { - { _sideBlock, _sideBlock, _strcBlock, _sideBlock, _sideBlock }, - { _sideBlock, _sideBlock, _strcBlock, _sideBlock, _sideBlock }, - { _strcBlock, _strcBlock, _strcBlock, _strcBlock, _strcBlock }, - { _sideBlock, _sideBlock, _strcBlock, _sideBlock, _sideBlock }, - { _sideBlock, _sideBlock, _strcBlock, _sideBlock, _sideBlock } - } - } ), - innerBuildable.hasAttribute( "completeness" ) - ? Double.parseDouble( innerBuildable.getAttributeValue("completeness") ) - : 1 ); - primitives.add( - new EmptyBox( - position, - size, - _bottomFill, - _topFill, - _sideFill, - _stroke, - new Point( 1, 1, 1 ), - new Point( 1, 1, 1 ) ) - ); - } - - private void prepareSigns( ) { - //Wall signs outside - primitives.add(new WallSign(position.getX() + size.getX() / 2, position.getY() + 3, position.getZ() - 1, WallSign.Orientation.NORTH, innerBuildable.getName())); - primitives.add(new WallSign(position.getX() + size.getX() / 2, position.getY() + 3, position.getZ() + size.getZ(), WallSign.Orientation.SOUTH, innerBuildable.getName())); - primitives.add(new WallSign(position.getX() - 1, position.getY() + 3, position.getZ() + size.getZ() / 2, WallSign.Orientation.WEST, innerBuildable.getName())); - primitives.add(new WallSign(position.getX() + size.getX(), position.getY() + 3, position.getZ() + size.getZ() / 2, WallSign.Orientation.EAST, innerBuildable.getName())); - //Wall signs inside - primitives.add(new WallSign(position.getX() + size.getX() / 2, position.getY() + 3, position.getZ() + 1, WallSign.Orientation.SOUTH, innerBuildable.getName())); - primitives.add(new WallSign(position.getX() + size.getX() / 2, position.getY() + 3, position.getZ() + size.getZ() - 2, WallSign.Orientation.NORTH, innerBuildable.getName())); - primitives.add(new WallSign(position.getX() + 1, position.getY() + 3, position.getZ() + size.getZ() / 2, WallSign.Orientation.EAST, innerBuildable.getName())); - primitives.add(new WallSign(position.getX() + size.getX() - 2, position.getY() + 3, position.getZ() + size.getZ() / 2, WallSign.Orientation.WEST, innerBuildable.getName())); + new RepeationPattern( + new BasicBlock[][][] { { { _sideBlock, _sideBlock, _strcBlock, _sideBlock, _sideBlock }, + { _sideBlock, _sideBlock, _strcBlock, _sideBlock, _sideBlock }, + { _strcBlock, _strcBlock, _strcBlock, _strcBlock, _strcBlock }, + { _sideBlock, _sideBlock, _strcBlock, _sideBlock, _sideBlock }, + { _sideBlock, _sideBlock, _strcBlock, _sideBlock, _sideBlock } } }), + innerBuildable.hasAttribute("completeness") + ? Double.parseDouble(innerBuildable.getAttributeValue("completeness")) + : 1); + walls.add(new EmptyBox(position, size, _bottomFill, _topFill, _sideFill, _stroke, new Point(1, 1, 1), + new Point(1, 1, 1))); + return walls; } - - private void prepareTorches( ) { - - if(!innerBuildable.hasAttribute( "torches" )) return; + + protected LinkedList prepareSigns() { + LinkedList signs = new LinkedList<>(); + + // Wall signs outside + signs.add(new WallSign(position.getX() + size.getX() / 2, position.getY() + 3, position.getZ() - 1, + WallSign.Orientation.NORTH, innerBuildable.getName())); + signs.add(new WallSign(position.getX() + size.getX() / 2, position.getY() + 3, position.getZ() + size.getZ(), + WallSign.Orientation.SOUTH, innerBuildable.getName())); + signs.add(new WallSign(position.getX() - 1, position.getY() + 3, position.getZ() + size.getZ() / 2, + WallSign.Orientation.WEST, innerBuildable.getName())); + signs.add(new WallSign(position.getX() + size.getX(), position.getY() + 3, position.getZ() + size.getZ() / 2, + WallSign.Orientation.EAST, innerBuildable.getName())); + // Wall signs inside + signs.add(new WallSign(position.getX() + size.getX() / 2, position.getY() + 3, position.getZ() + 1, + WallSign.Orientation.SOUTH, innerBuildable.getName())); + signs.add(new WallSign(position.getX() + size.getX() / 2, position.getY() + 3, + position.getZ() + size.getZ() - 2, WallSign.Orientation.NORTH, innerBuildable.getName())); + signs.add(new WallSign(position.getX() + 1, position.getY() + 3, position.getZ() + size.getZ() / 2, + WallSign.Orientation.EAST, innerBuildable.getName())); + signs.add(new WallSign(position.getX() + size.getX() - 2, position.getY() + 3, + position.getZ() + size.getZ() / 2, WallSign.Orientation.WEST, innerBuildable.getName())); + signs.add(new WallSign(position.getX() + size.getX() - 2, position.getY() + 3, + position.getZ() + size.getZ() / 2, WallSign.Orientation.WEST, innerBuildable.getName())); + //METRIC WALL signs + signs.add(new WallSign(position.getX() + size.getX() - 2, position.getY() + 3, + position.getZ() + size.getZ() / 2, WallSign.Orientation.WEST, "First metric: "+Integer.toString(BuiltMetric1))); + signs.add(new WallSign(position.getX() + size.getX() - 2, position.getY() + 3, + position.getZ() + (size.getZ() / 2) + 1, WallSign.Orientation.WEST, "Second metric: "+Integer.toString(BuiltMetric2))); + signs.add(new WallSign(position.getX() + size.getX() - 2, position.getY() + 3, + position.getZ() + (size.getZ() / 2) - 1, WallSign.Orientation.WEST, "Third metric: "+Integer.toString(BuiltMetric3))); + return signs; + } + + protected LinkedList prepareTorches() { + LinkedList torches = new LinkedList<>(); + + if (!innerBuildable.hasAttribute("torches")) + return torches; + int numberOfTorches = Integer.parseInt(innerBuildable.getAttributeValue("torches")); BasicBlock[] pattern; - + pattern = createTorchPattern(numberOfTorches, 3); - primitives.add(new Row( - new Point(position.getX() + size.getX() / 2 + 2, position.getY() + 2, position.getZ() + 1), - size.getX() / 2 - 2, - Row.Direction.WEST, - pattern)); - - primitives.add(new Row( - new Point(position.getX() + size.getX() / 2 - 2, position.getY() + 2, position.getZ() + 1), - size.getX() / 2 - 2, - Row.Direction.EAST, - pattern)); - + torches.add(new Row(new Point(position.getX() + size.getX() / 2 + 2, position.getY() + 2, position.getZ() + 1), + size.getX() / 2 - 2, Row.Direction.WEST, pattern, BlockFacing.SOUTH)); + + torches.add(new Row(new Point(position.getX() + size.getX() / 2 - 2, position.getY() + 2, position.getZ() + 1), + size.getX() / 2 - 2, Row.Direction.EAST, pattern, BlockFacing.SOUTH)); + pattern = createTorchPattern(numberOfTorches, 4); - primitives.add(new Row( - new Point(position.getX() + size.getX() / 2 + 2, position.getY() + 2, position.getZ() + size.getZ() - 2), - size.getX() / 2 - 2, - Row.Direction.WEST, - pattern)); - - primitives.add(new Row( - new Point(position.getX() + size.getX() / 2 - 2, position.getY() + 2, position.getZ() + size.getZ() - 2), - size.getX() / 2 - 2, - Row.Direction.EAST, - pattern)); - + torches.add(new Row( + new Point(position.getX() + size.getX() / 2 + 2, position.getY() + 2, + position.getZ() + size.getZ() - 2), + size.getX() / 2 - 2, Row.Direction.WEST, pattern, BlockFacing.NORTH)); + + torches.add(new Row( + new Point(position.getX() + size.getX() / 2 - 2, position.getY() + 2, + position.getZ() + size.getZ() - 2), + size.getX() / 2 - 2, Row.Direction.EAST, pattern, BlockFacing.NORTH)); + pattern = createTorchPattern(numberOfTorches, 1); - primitives.add(new Row( - new Point(position.getX() + 1, position.getY() + 2, position.getZ() + size.getZ() / 2 + 2), - size.getZ() / 2 - 2, - Row.Direction.NORTH, - pattern)); - - primitives.add(new Row( - new Point(position.getX() + 1, position.getY() + 2, position.getZ() + size.getZ() / 2 - 2), - size.getZ() / 2 - 2, - Row.Direction.SOUTH, - pattern)); - + torches.add(new Row(new Point(position.getX() + 1, position.getY() + 2, position.getZ() + size.getZ() / 2 + 2), + size.getZ() / 2 - 2, Row.Direction.NORTH, pattern, BlockFacing.EAST)); + + torches.add(new Row(new Point(position.getX() + 1, position.getY() + 2, position.getZ() + size.getZ() / 2 - 2), + size.getZ() / 2 - 2, Row.Direction.SOUTH, pattern, BlockFacing.EAST)); + pattern = createTorchPattern(numberOfTorches, 2); - primitives.add(new Row( - new Point(position.getX() + size.getX() - 2, position.getY() + 2, position.getZ() + size.getZ() / 2 + 2), - size.getZ() / 2 - 2, - Row.Direction.NORTH, - pattern)); - - primitives.add(new Row( - new Point(position.getX() + size.getX() - 2, position.getY() + 2, position.getZ() + size.getZ() / 2 - 2), - size.getZ() / 2 - 2, - Row.Direction.SOUTH, - pattern)); - + torches.add(new Row( + new Point(position.getX() + size.getX() - 2, position.getY() + 2, + position.getZ() + size.getZ() / 2 + 2), + size.getZ() / 2 - 2, Row.Direction.NORTH, pattern, BlockFacing.WEST)); + + torches.add(new Row( + new Point(position.getX() + size.getX() - 2, position.getY() + 2, + position.getZ() + size.getZ() / 2 - 2), + size.getZ() / 2 - 2, Row.Direction.SOUTH, pattern, BlockFacing.WEST)); + + return torches; } - - private BasicBlock[] createTorchPattern(int number, int data) { + + protected BasicBlock[] createTorchPattern(int number, int data) { BasicBlock[] pattern = null; - BasicBlock torch = new BasicBlock((short) 50, data); - BasicBlock space = BasicBlock.NonBlock; - - switch(number) { - case 0: - pattern = new BasicBlock[] { space }; - break; - case 1: - pattern = new BasicBlock[] { torch, space, space, space, space }; - break; - case 2: - pattern = new BasicBlock[] { torch, space, space, space }; - break; - case 3: - pattern = new BasicBlock[] { torch, space, space }; - break; - case 4: - pattern = new BasicBlock[] { torch, space }; - break; - case 5: - pattern = new BasicBlock[] { torch }; - break; + BasicBlock torch = BasicBlock.TORCH; + BasicBlock space = BasicBlock.NON_BLOCK; + + switch (number) { + case 0: + pattern = new BasicBlock[] { space }; + break; + case 1: + pattern = new BasicBlock[] { torch, space, space, space, space }; + break; + case 2: + pattern = new BasicBlock[] { torch, space, space, space }; + break; + case 3: + pattern = new BasicBlock[] { torch, space, space }; + break; + case 4: + pattern = new BasicBlock[] { torch, space }; + break; + case 5: + pattern = new BasicBlock[] { torch }; + break; } return pattern; } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Garden.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Garden.java index 88b163b9..3bbac96a 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Garden.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Garden.java @@ -1,5 +1,7 @@ package codemetropolis.toolchain.rendering.model.building; +import java.util.LinkedList; + import codemetropolis.toolchain.commons.cmxml.Buildable; import codemetropolis.toolchain.commons.cmxml.Buildable.Type; import codemetropolis.toolchain.commons.cmxml.Point; @@ -8,141 +10,172 @@ import codemetropolis.toolchain.rendering.model.pattern.RandomPattern; import codemetropolis.toolchain.rendering.model.pattern.RepeationPattern; import codemetropolis.toolchain.rendering.model.pattern.YSplitPattern; +import codemetropolis.toolchain.rendering.model.primitive.Mob; +import codemetropolis.toolchain.rendering.model.primitive.Primitive; import codemetropolis.toolchain.rendering.model.primitive.SignPost; import codemetropolis.toolchain.rendering.model.primitive.SolidBox; +import codemetropolis.toolchain.rendering.model.primitive.Spawner; import codemetropolis.toolchain.rendering.util.Orientation; public class Garden extends Building { + int monster_count; + private int BuiltNumber1=0; + private int BuiltNumber2=0; + private int BuiltNumber3=0; public Garden(Buildable innerBuildable) throws BuildingTypeMismatchException { super(innerBuildable); - - if ( innerBuildable.getType() != Type.GARDEN ) + + if (innerBuildable.getType() != Type.GARDEN) throw new BuildingTypeMismatchException(innerBuildable.getType(), getClass()); - prepareBase(); - prepareDoor(); - prepareSigns(); + primitives.addAll(prepareBase()); + primitives.addAll(prepareDoor()); + primitives.addAll(prepareSigns()); + primitives.addAll(prepareSpawners()); + primitives.addAll(prepareSignsForSpawners()); + primitives.addAll(prepareMobs()); } - private void prepareBase( ) { - BasicBlock _fnc = new BasicBlock( "minecraft:fence" ); - BasicBlock _sns = new BasicBlock( "minecraft:sandstone" ); - RandomPattern _flowers = new RandomPattern( new RepeationPattern( new BasicBlock[][][]{ { { BasicBlock.NonBlock } } } ) ); + public int getBuiltNumber1() { + return BuiltNumber1; + } + + public void setBuiltNumber1(int builtNumber1) { + BuiltNumber1 = builtNumber1; + } + + public int getBuiltNumber2() { + return BuiltNumber2; + } + + public void setBuiltNumber2(int builtNumber2) { + BuiltNumber2 = builtNumber2; + } + + public int getBuiltNumber3() { + return BuiltNumber3; + } + + public void setBuiltNumber3(int builtNumber3) { + BuiltNumber3 = builtNumber3; + } + + protected LinkedList prepareBase() { + BasicBlock _fnc = BasicBlock.FENCE; + BasicBlock _sns = BasicBlock.SANDSTONE; + LinkedList repeatPattern = new LinkedList<>(); - RandomPattern _redOrYellow = new RandomPattern( new RepeationPattern( new BasicBlock[][][]{ { { new BasicBlock( "minecraft:yellow_flower" ) } } } ) ); - _redOrYellow.add(new RepeationPattern( new BasicBlock[][][]{ { { new BasicBlock( "minecraft:red_flower" ) } } } ), 0.5); - _flowers.add( - _redOrYellow, - innerBuildable.hasAttribute( "flower-ratio" ) - ? Double.parseDouble( innerBuildable.getAttributeValue("flower-ratio") ) - : 0 ); - _flowers.add( - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:brown_mushroom" ) } } } ), - innerBuildable.hasAttribute( "mushroom-ratio" ) - ? Double.parseDouble( innerBuildable.getAttributeValue("mushroom-ratio") ) - : 0 ); - _flowers.add( - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:sapling" ) } } } ), - innerBuildable.hasAttribute( "tree-ratio" ) - ? Double.parseDouble( innerBuildable.getAttributeValue("tree-ratio") ) - : 0 ); - primitives.add( - new SolidBox( - position, new Point( size.getX(), 2, size.getZ() ), - new YSplitPattern( - 0, - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:grass" ) } } } ), - _flowers ), - new RepeationPattern( - new BasicBlock[][][] - { - { - { _fnc }, - { _sns } - } - } ), - Orientation.NearX ) ); + monster_count = innerBuildable.hasAttribute("monster-count") + ? Integer.parseInt( innerBuildable.getAttributeValue ("monster-count") ) + : 0; + + RandomPattern _flowers = new RandomPattern( + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.NON_BLOCK } } })); + + RandomPattern _redOrYellow = new RandomPattern( + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.DANDELION } } })); + _redOrYellow.add(new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.POPPY } } }), 0.5); + _flowers.add(_redOrYellow, + innerBuildable.hasAttribute("flower-ratio") + ? Double.parseDouble(innerBuildable.getAttributeValue("flower-ratio")) + : 0); + _flowers.add(new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.BROWN_MUSHROOM } } }), + innerBuildable.hasAttribute("mushroom-ratio") + ? Double.parseDouble(innerBuildable.getAttributeValue("mushroom-ratio")) + : 0); + _flowers.add(new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.OAK_SAPLING } } }), + innerBuildable.hasAttribute("tree-ratio") + ? Double.parseDouble(innerBuildable.getAttributeValue("tree-ratio")) + : 0); + repeatPattern.add(new SolidBox(position, new Point(size.getX(), 2, size.getZ()), + new YSplitPattern(0, new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.GRASS_BLOCK } } }), + _flowers), + new RepeationPattern(new BasicBlock[][][] { { { _fnc }, { _sns } } }), Orientation.NearX)); + + return repeatPattern; + + } - - protected void prepareDoor( ) - { - BasicBlock _fnc = new BasicBlock( "minecraft:fence" ); - BasicBlock _rwl = new BasicBlock( "minecraft:wool", 14 ); - BasicBlock _gwl = new BasicBlock( "minecraft:wool", 5 ); - BasicBlock _bwl = new BasicBlock( "minecraft:wool", 3 ); - BasicBlock _ywl = new BasicBlock( "minecraft:wool", 4 ); - primitives.add( - new SolidBox( - position.translate( new Point( center.getX() - 1, 0, 0 ) ), new Point( 3, 4, 1 ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air", 2 ) } } } ), - new RepeationPattern( - new BasicBlock[][][] - { - { - { _fnc }, - { _fnc }, - { _fnc }, - { _rwl } - } - } ), - Orientation.NearX ) - ); - primitives.add( - new SolidBox( - position.translate( new Point( center.getX() - 1, 0, size.getZ() - 1 ) ), new Point( 3, 4, 1 ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air", 2 ) } } } ), - new RepeationPattern( - new BasicBlock[][][] - { - { - { _fnc }, - { _fnc }, - { _fnc }, - { _gwl } - } - } ), - Orientation.NearX ) - ); - primitives.add( - new SolidBox( - position.translate( new Point( 0, 0, center.getZ()-1 ) ), new Point( 1, 4, 3 ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air", 2 ) } } } ), - new RepeationPattern( - new BasicBlock[][][] - { - { - { _fnc }, - { _fnc }, - { _fnc }, - { _bwl } - } - } ), - Orientation.NearX ) - ); - primitives.add( - new SolidBox( - position.translate( new Point( size.getX()-1, 0, center.getZ() - 1 ) ), new Point( 1, 4, 3 ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:air", 2 ) } } } ), - new RepeationPattern( - new BasicBlock[][][] - { - { - { _fnc }, - { _fnc }, - { _fnc }, - { _ywl } - } - } ), - Orientation.NearX ) - ); + + protected LinkedList prepareDoor() { + + LinkedList doors = new LinkedList<>(); + + BasicBlock _fnc = BasicBlock.FENCE; + BasicBlock _rwl = BasicBlock.RED_WOOL; + BasicBlock _gwl = BasicBlock.GREENWOOL; + BasicBlock _bwl = BasicBlock.BLUE_WOOL; + BasicBlock _ywl = BasicBlock.YELLOW_WOOL; + doors.add(new SolidBox(position.translate(new Point(center.getX() - 1, 0, 0)), new Point(3, 4, 1), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), + new RepeationPattern(new BasicBlock[][][] { { { _fnc }, { _fnc }, { _fnc }, { _rwl } } }), + Orientation.NearX)); + doors.add(new SolidBox(position.translate(new Point(center.getX() - 1, 0, size.getZ() - 1)), new Point(3, 4, 1), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), + new RepeationPattern(new BasicBlock[][][] { { { _fnc }, { _fnc }, { _fnc }, { _gwl } } }), + Orientation.NearX)); + doors.add(new SolidBox(position.translate(new Point(0, 0, center.getZ() - 1)), new Point(1, 4, 3), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), + new RepeationPattern(new BasicBlock[][][] { { { _fnc }, { _fnc }, { _fnc }, { _bwl } } }), + Orientation.NearX)); + doors.add(new SolidBox(position.translate(new Point(size.getX() - 1, 0, center.getZ() - 1)), new Point(1, 4, 3), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.AIR } } }), + new RepeationPattern(new BasicBlock[][][] { { { _fnc }, { _fnc }, { _fnc }, { _ywl } } }), + Orientation.NearX)); + + return doors; } - - private void prepareSigns( ) { - primitives.add(new SignPost(position.getX(), position.getY() + 2, position.getZ(), SignPost.Orientation.NORTHWEST, innerBuildable.getName())); - primitives.add(new SignPost(position.getX() + size.getX() - 1, position.getY() + 2, position.getZ(), SignPost.Orientation.NORTHEAST, innerBuildable.getName())); - primitives.add(new SignPost(position.getX(), position.getY() + 2, position.getZ() + size.getZ() - 1, SignPost.Orientation.SOUTHWEST, innerBuildable.getName())); - primitives.add(new SignPost(position.getX() + size.getX() - 1, position.getY() + 2, position.getZ() + size.getZ() - 1, SignPost.Orientation.SOUTHEAST, innerBuildable.getName())); + + protected LinkedList prepareSigns() { + LinkedList signs = new LinkedList<>(); + + signs.add(new SignPost(position.getX(), position.getY() + 2, position.getZ(), SignPost.Orientation.NORTHWEST, + innerBuildable.getName())); + signs.add(new SignPost(position.getX() + size.getX() - 1, position.getY() + 2, position.getZ(), + SignPost.Orientation.NORTHEAST, innerBuildable.getName())); + signs.add(new SignPost(position.getX(), position.getY() + 2, position.getZ() + size.getZ() - 1, + SignPost.Orientation.SOUTHWEST, innerBuildable.getName())); + signs.add(new SignPost(position.getX() + size.getX() - 1, position.getY() + 2, + position.getZ() + size.getZ() - 1, SignPost.Orientation.SOUTHEAST, innerBuildable.getName())); + + return signs; + } + + protected LinkedList prepareSpawners() { + LinkedList spawners = new LinkedList<>(); + if (monster_count > 0) spawners.add(new Spawner(position.getX() + size.getX() / 2, position.getY(), position.getZ() - 3)); + if (monster_count > 1) spawners.add(new Spawner(position.getX() + size.getX() / 2, position.getY(), position.getZ() + size.getZ() + 2)); + if (monster_count > 2) spawners.add(new Spawner(position.getX() - 3, position.getY(), position.getZ() + size.getZ() / 2)); + if (monster_count > 3) spawners.add(new Spawner(position.getX() + size.getX() + 2, position.getY(), position.getZ() + size.getZ() / 2)); + + return spawners; + } + + protected LinkedList prepareSignsForSpawners() { + LinkedList signSpawners = new LinkedList<>(); + String signName = innerBuildable.hasAttribute("monster-label") ? (innerBuildable.getAttributeValue("monster-label")) : ""; + + switch (monster_count) { + case 4: + signSpawners.add(new SignPost(position.getX() + size.getX() + 2, position.getY(), position.getZ() + size.getZ() / 2 + 1, SignPost.Orientation.EAST, signName)); + signSpawners.add(new SignPost(position.getX() + size.getX() + 2, position.getY(), position.getZ() + size.getZ() / 2 - 1, SignPost.Orientation.EAST, signName)); + case 3: + signSpawners.add(new SignPost(position.getX() - 3, position.getY(), position.getZ() + size.getZ() / 2 + 1, SignPost.Orientation.WEST, signName)); + signSpawners.add(new SignPost(position.getX() - 3, position.getY(), position.getZ() + size.getZ() / 2 - 1, SignPost.Orientation.WEST, signName)); + case 2: + signSpawners.add(new SignPost(position.getX() + size.getX() / 2 - 1, position.getY(), position.getZ() + size.getZ() + 2, SignPost.Orientation.SOUTH, signName)); + signSpawners.add(new SignPost(position.getX() + size.getX() / 2 + 1, position.getY(), position.getZ() + size.getZ() + 2, SignPost.Orientation.SOUTH, signName)); + case 1: + signSpawners.add(new SignPost(position.getX() + size.getX() / 2 - 1, position.getY(), position.getZ() - 3, SignPost.Orientation.NORTH, signName)); + signSpawners.add(new SignPost(position.getX() + size.getX() / 2 + 1, position.getY(), position.getZ() - 3, SignPost.Orientation.NORTH, signName)); + } + return signSpawners; + } + protected LinkedList prepareMobs() { + LinkedList prepMob = new LinkedList<>(); + prepMob.add(new Mob(position.getX() + size.getX()/2, position.getY() + 2, position.getZ() + size.getZ()/2, innerBuildable.getName())); + return prepMob; } } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Ground.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Ground.java index b7f24d6f..5943ecfd 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Ground.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Ground.java @@ -1,11 +1,14 @@ package codemetropolis.toolchain.rendering.model.building; +import java.util.LinkedList; + import codemetropolis.toolchain.commons.cmxml.Buildable; import codemetropolis.toolchain.commons.cmxml.Buildable.Type; import codemetropolis.toolchain.commons.cmxml.Point; import codemetropolis.toolchain.rendering.exceptions.BuildingTypeMismatchException; import codemetropolis.toolchain.rendering.model.BasicBlock; import codemetropolis.toolchain.rendering.model.pattern.RepeationPattern; +import codemetropolis.toolchain.rendering.model.primitive.Primitive; import codemetropolis.toolchain.rendering.model.primitive.SignPost; import codemetropolis.toolchain.rendering.model.primitive.SolidBox; import codemetropolis.toolchain.rendering.util.Orientation; @@ -15,28 +18,36 @@ public class Ground extends Building { public Ground(Buildable innerBuildable) throws BuildingTypeMismatchException { super(innerBuildable); - if ( innerBuildable.getType() != Type.GROUND ) + if (innerBuildable.getType() != Type.GROUND) throw new BuildingTypeMismatchException(innerBuildable.getType(), getClass()); - prepareBase(); - prepareSigns(); + primitives.addAll(prepareBase()); + primitives.addAll(prepareSigns()); } - - private void prepareBase( ) { - primitives.add( - new SolidBox( - position, - new Point( size.getX(), 1, size.getZ() ), - new RepeationPattern( new BasicBlock[][][]{ { { new BasicBlock( "minecraft:stone" ) } } } ), - new RepeationPattern( new BasicBlock[][][] { { { new BasicBlock( "minecraft:stonebrick" ) } } } ), - Orientation.NearX ) ); + + + protected LinkedList prepareBase() { + + LinkedList base = new LinkedList<>(); + base.add(new SolidBox(position, new Point(size.getX(), 1, size.getZ()), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.STONE } } }), + new RepeationPattern(new BasicBlock[][][] { { { BasicBlock.STONE_BRICKS } } }), Orientation.NearX)); + return base; } - - private void prepareSigns( ) { - primitives.add(new SignPost(position.getX(), position.getY() + 1, position.getZ(), SignPost.Orientation.NORTHWEST, innerBuildable.getName())); - primitives.add(new SignPost(position.getX() + size.getX() - 1, position.getY() + 1, position.getZ(), SignPost.Orientation.NORTHEAST, innerBuildable.getName())); - primitives.add(new SignPost(position.getX(), position.getY() + 1, position.getZ() + size.getZ() - 1, SignPost.Orientation.SOUTHWEST, innerBuildable.getName())); - primitives.add(new SignPost(position.getX() + size.getX() - 1, position.getY() + 1, position.getZ() + size.getZ() - 1, SignPost.Orientation.SOUTHEAST, innerBuildable.getName())); + + protected LinkedList prepareSigns() { + LinkedList signs = new LinkedList<>(); + + signs.add(new SignPost(position.getX(), position.getY() + 1, position.getZ(), SignPost.Orientation.NORTHWEST, + innerBuildable.getName())); + signs.add(new SignPost(position.getX() + size.getX() - 1, position.getY() + 1, position.getZ(), + SignPost.Orientation.NORTHEAST, innerBuildable.getName())); + signs.add(new SignPost(position.getX(), position.getY() + 1, position.getZ() + size.getZ() - 1, + SignPost.Orientation.SOUTHWEST, innerBuildable.getName())); + signs.add(new SignPost(position.getX() + size.getX() - 1, position.getY() + 1, + position.getZ() + size.getZ() - 1, SignPost.Orientation.SOUTHEAST, innerBuildable.getName())); + return signs; + } } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Linking.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Linking.java new file mode 100644 index 00000000..3d5c8808 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Linking.java @@ -0,0 +1,208 @@ +package codemetropolis.toolchain.rendering.model.building; + +import codemetropolis.toolchain.commons.cmxml.Buildable; +import codemetropolis.toolchain.commons.cmxml.Point; +import codemetropolis.toolchain.commons.cmxml.Buildable.Type; +import codemetropolis.toolchain.rendering.exceptions.RenderingException; +import codemetropolis.toolchain.rendering.model.BasicBlock; +import codemetropolis.toolchain.rendering.model.pattern.RepeationPattern; +import codemetropolis.toolchain.rendering.model.primitive.SolidBox; +import codemetropolis.toolchain.rendering.util.Orientation; + +public abstract class Linking extends Building { + public static final int MIN_SIZE = 2; + public static final String LINKING_ATTRIBUTE_TARGET = "target"; + public static final String LINKING_ATTRIBUTE_STANDALONE = "standalone"; + public static final String LINKING_ATTRIBUTE_ORIENTATION = "orientation"; + + protected boolean standalone; + protected String orientation; + protected int level; + protected int height; + protected int width; + + public Linking(Buildable innerBuildable) throws RenderingException { + + this.innerBuildable = innerBuildable; + + + if (this.innerBuildable.hasAttribute(LINKING_ATTRIBUTE_STANDALONE)) { + this.standalone = Boolean.parseBoolean(this.innerBuildable.getAttributeValue(LINKING_ATTRIBUTE_STANDALONE)); + } else { + throw new RenderingException(LINKING_ATTRIBUTE_STANDALONE + " attribute not present in Linking."); + } + + if (this.innerBuildable.hasAttribute(LINKING_ATTRIBUTE_ORIENTATION)) { + this.orientation = this.innerBuildable.getAttributeValue(LINKING_ATTRIBUTE_ORIENTATION); + } else { + throw new RenderingException(LINKING_ATTRIBUTE_ORIENTATION + " attribute not present in Linking."); + } + + size = new Point( + adjustSize(innerBuildable.getSizeX(), MIN_SIZE), + adjustSize(innerBuildable.getSizeY(), MIN_SIZE), + adjustSize(innerBuildable.getSizeZ(), MIN_SIZE) + ); + + position = new Point( + innerBuildable.getPositionX(), + innerBuildable.getPositionY(), + innerBuildable.getPositionZ() + ); + + center = new Point( + (int)(size.getX() * 0.5), + (int)(size.getY() * 0.5), + (int)(size.getZ() * 0.5) + ); + } + + protected void prepareLinking(BasicBlock[][][] material) { + + primitives.add( + new SolidBox( + new Point(position.getX(), level, position.getZ()), + new Point(size.getX(), this.height, size.getZ()), + new RepeationPattern( material), + new RepeationPattern( material ), + Orientation.NearX ) ); + + } + + public void prepareStairs() { + BasicBlock _air = BasicBlock.AIR; + BasicBlock _str = BasicBlock.STONE; + BasicBlock _cre = BasicBlock.FENCE; + + BasicBlock[][][] steps = + new BasicBlock[][][] + { + { + { _str, _air, _air }, + { _air, _cre, _air }, + { _air, _air, _air } + }, + { + { _air, _str, _air }, + { _air, _cre, _air }, + { _air, _air, _air } + }, + { + { _air, _air, _str }, + { _air, _cre, _air }, + { _air, _air, _air } + }, + { + { _air, _air, _air }, + { _air, _cre, _str }, + { _air, _air, _air } + }, + { + { _air, _air, _air }, + { _air, _cre, _air }, + { _air, _air, _str } + }, + { + { _air, _air, _air }, + { _air, _cre, _air }, + { _air, _str, _air } + }, + { + { _air, _air, _air }, + { _air, _cre, _air }, + { _str, _air, _air } + }, + { + { _air, _air, _air }, + { _str, _cre, _air }, + { _air, _air, _air } + } + }; + + if ((this.innerBuildable.getType() == Type.TUNNEL && !this.innerBuildable.getParent().hasLowerStairs()) || + (!this.innerBuildable.getParent().hasUpperStairs() && this.innerBuildable.getType() == Type.BRIDGE)) { + + if(this.innerBuildable.getType() == Type.TUNNEL) { + this.innerBuildable.getParent().setHasLowerStairs(true); + } else { + this.innerBuildable.getParent().setHasUpperStairs(true); + } + + primitives.add( + new SolidBox( + calculateStepPosition(false), + new Point( 3, calculateHeight(this.innerBuildable.getParent()) + this.height, 3 ), + new RepeationPattern( steps ), + new RepeationPattern( steps ), + Orientation.NearY ) ); + } + + if (standalone) { + + String id = this.innerBuildable.getAttributeValue(LINKING_ATTRIBUTE_TARGET); + + if (id == null) { return; } + + Buildable root = this.innerBuildable.getParent(); + while(!root.isRoot()) { + root = root.getParent(); + } + + Buildable target = getTarget(root, id); + if (target == null || (this.innerBuildable.getType() == Type.TUNNEL && target.hasLowerStairs()) || (target.hasUpperStairs() && this.innerBuildable.getType() == Type.BRIDGE)) { return; } + + if (this.innerBuildable.getType() == Type.TUNNEL) { + target.setHasLowerStairs(true); + } else { + target.setHasUpperStairs(true); + } + + primitives.add( + new SolidBox( + calculateStepPosition(true), + new Point( 3, calculateHeight(target) + this.height, 3 ), + new RepeationPattern( steps ), + new RepeationPattern( steps ), + Orientation.NearY ) ); + } + + } + + + public Buildable getTarget(Buildable buildable, String id) { + Buildable b = null; + + if (id.equals(buildable.getId())) { + return buildable; + } else if (buildable.getNumberOfChildren() == 0) { + return null; + } else { + for(Buildable child : buildable.getChildren()) { + b = getTarget(child, id); + + if (b != null) { break; } + } + } + return b; + } + + public abstract int calculateHeight(Buildable buildable); + + public abstract Point calculateStepPosition(boolean isTarget); + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } +} diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Number.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Number.java new file mode 100644 index 00000000..1156a4d1 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Number.java @@ -0,0 +1,713 @@ +package codemetropolis.toolchain.rendering.model.building; + +import java.util.LinkedList; +import codemetropolis.toolchain.commons.cmxml.Buildable; +import codemetropolis.toolchain.commons.cmxml.Point; +import codemetropolis.toolchain.rendering.model.BasicBlock; +import codemetropolis.toolchain.rendering.model.pattern.RepeationPattern; +import codemetropolis.toolchain.rendering.model.primitive.*; +import codemetropolis.toolchain.rendering.util.Orientation; + + + +/** + * Created by Gábor on 2017. 04. 03.. + */ +public class Number extends Building{ + + + protected int GardenPositionX; + protected int GardenPositionZ; + protected int GardenPositionY; + protected int numberToBuild; + protected int positionZ; + + + + public Number(Buildable Garden,String metricToBuild){ + super(Garden); + + GardenPositionX=Garden.getPositionX(); + GardenPositionZ=Garden.getPositionZ(); + GardenPositionY=Garden.getPositionY(); + + + switch(metricToBuild){ + case "BuiltMetric1": + numberToBuild=Garden.getBuiltMetric1(); + positionZ=GardenPositionZ +1; + Point posBuiltMetric1=new Point(GardenPositionX,GardenPositionY+4,positionZ); + setPosition(posBuiltMetric1); + break; + case "BuiltMetric2": + numberToBuild=Garden.getBuiltMetric2(); + positionZ=GardenPositionZ +6; + Point posBuiltMetric2=new Point(GardenPositionX,GardenPositionY+4,positionZ); + setPosition(posBuiltMetric2); + break; + case "BuiltMetric3": + numberToBuild=Garden.getBuiltMetric3(); + positionZ=GardenPositionZ +11; + Point posBuiltMetric3=new Point(GardenPositionX,GardenPositionY+4,positionZ); + setPosition(posBuiltMetric3); + break; + + } + prepareNumber(numberToBuild,positionZ); + } + + protected LinkedList prepareNumber(int number,int positionZ){ + LinkedList numbers = new LinkedList<>(); + BasicBlock _air = BasicBlock.AIR; + BasicBlock _str = BasicBlock.STONE; + + if(number==0){ + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + + } + int tmp; + int PositionShift=0; + while(number>0) + { + + tmp=number%10; + number=number/10; + + switch(tmp) { + case 9: + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4+PositionShift, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _air,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + break; + + case 8: + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4+PositionShift, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + break; + + case 7: + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4+PositionShift, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _air,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _air,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _air,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _air,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + break; + case 6: + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4+PositionShift, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + break; + case 5: + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4+PositionShift, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _air,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + break; + case 4: + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4+PositionShift, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _str, _air,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + break; + case 3: + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4+PositionShift, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _air,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _air,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _air,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + break; + case 2: + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4+PositionShift, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _air,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + break; + case 1: + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4+PositionShift, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _str, _air,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _str, _air,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_air, _str, _air,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + break; + case 0: + numbers.add( + new SolidBox( + new Point( GardenPositionX - 1, GardenPositionY+4+PositionShift, positionZ ) , + new Point( 3, 5, 5 ), + + new RepeationPattern( + new BasicBlock[][][] + { + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air }, + { _air,_air, _air, _air,_air } + + + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _air, _str,_air }, + { _air,_air, _air, _air,_air } + + + }, + { + + { _air,_air, _air, _air,_air }, + { _air,_str, _str, _str,_air}, + { _air,_air, _air, _air,_air } + + + } + + } ), + new RepeationPattern( new BasicBlock[][][] {{{BasicBlock.AIR}}} ), + + Orientation.NearY ) + ); + break; + } + PositionShift=PositionShift+6; + + } + return numbers; + } + + + + +} \ No newline at end of file diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Tunnel.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Tunnel.java new file mode 100644 index 00000000..edd42103 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/building/Tunnel.java @@ -0,0 +1,113 @@ +package codemetropolis.toolchain.rendering.model.building; + +import java.util.ArrayList; +import java.util.List; + +import codemetropolis.toolchain.commons.cmxml.Buildable; +import codemetropolis.toolchain.commons.cmxml.Buildable.Type; +import codemetropolis.toolchain.commons.cmxml.Point; +import codemetropolis.toolchain.rendering.control.WorldBuilder; +import codemetropolis.toolchain.rendering.exceptions.BuildingTypeMismatchException; +import codemetropolis.toolchain.rendering.exceptions.RenderingException; +import codemetropolis.toolchain.rendering.model.BasicBlock; +import codemetropolis.toolchain.rendering.model.pattern.RepeationPattern; +import codemetropolis.toolchain.rendering.model.primitive.SolidBox; +import codemetropolis.toolchain.rendering.util.Orientation; + +public class Tunnel extends Linking { + + private List lighting; + + public Tunnel(Buildable innerBuildable) throws RenderingException { + + super(innerBuildable); + + if ( innerBuildable.getType() != Type.TUNNEL ) { + throw new BuildingTypeMismatchException(innerBuildable.getType(), getClass()); + } + + this.height = 4; + this.width = 2; + + this.level = WorldBuilder.TUNNEL_LEVEL - this.getHeight(); + + prepareLinking(new BasicBlock[][][] { { { BasicBlock.AIR } } }); + + lighting = this.prepareLighting(); + } + + public int calculateHeight(Buildable buildable) { + return buildable.getPositionY() - level + this.height; + } + + public Point calculateStepPosition(boolean isTarget) { + Point stepPosition; + + if(!isTarget) { + if ("NORTH".equals(this.orientation)) { + stepPosition = new Point(position.getX(), level, position.getZ() + size.getZ() - adjustSize(this.width, MIN_SIZE)); + } else if ("SOUTH".equals(this.orientation)) { + stepPosition = new Point(position.getX(), level, position.getZ()); + } else if ("WEST".equals(this.orientation)) { + stepPosition = new Point(position.getX() + size.getX() - adjustSize(this.width, MIN_SIZE), level, position.getZ()); + } else { + stepPosition = new Point(position.getX(), level, position.getZ()); + } + } else { + if ("NORTH".equals(this.orientation)) { + stepPosition = new Point(position.getX(), level, position.getZ()); + } else if ("SOUTH".equals(this.orientation)) { + stepPosition = new Point(position.getX(), level, position.getZ() + size.getZ() - adjustSize(this.width, MIN_SIZE)); + } else if ("WEST".equals(this.orientation)) { + stepPosition = new Point(position.getX(), level, position.getZ()); + } else { + stepPosition = new Point(position.getX()+ size.getX() - adjustSize(this.width, MIN_SIZE), level, position.getZ()); + } + } + + return stepPosition; + } + + + protected List prepareLighting() { + // NOTE (wyvick) For now there is a redstone lamp line + // in each tunnel with redstone blocks below them. + + // TODO (wyvick) Since this is a SolidBox implementation, + // both the length and the width of the lamp line + // are cut by one block (to ensure that it is only a single line). + // Row implementation may work better as we would not need to cut + // and we could specify pattern with it as well, + // but orientation may cause a problem. + // (One possible solution is that we check whether the tunnel has + // North-South or West-East orientation, + // maybe by using width and length values.) + + // redstone lamps (single line in the middle of the tunnel floor) + + List lighting = new ArrayList(); + lighting.add(new SolidBox( + new Point(position.getX() + 1, this.level - 1, position.getZ() + 1), + new Point(size.getX() - 2, 1, size.getZ() - 2), + new RepeationPattern( new BasicBlock[][][]{ { { BasicBlock.REDSTONE_LAMP } } } ), + new RepeationPattern( new BasicBlock[][][]{ { { BasicBlock.REDSTONE_LAMP } } } ), + Orientation.NearX + )); + + // redstone blocks under lamps + lighting.add(new SolidBox( + new Point(position.getX() + 1, this.level - 2, position.getZ() + 1), + new Point(size.getX() - 2, 1, size.getZ() - 2), + new RepeationPattern( new BasicBlock[][][]{ { { BasicBlock.REDSTONE_BLOCK } } } ), + new RepeationPattern( new BasicBlock[][][]{ { { BasicBlock.REDSTONE_BLOCK } } } ), + Orientation.NearX + )); + primitives.addAll(lighting); + return lighting; + } + + public List getLighting() { + return lighting; + } + +} diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Banner.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Banner.java index f2a1dd13..e196e6e7 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Banner.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Banner.java @@ -1,52 +1,52 @@ package codemetropolis.toolchain.rendering.model.primitive; import java.io.File; +import java.util.HashMap; +import java.util.Map; import codemetropolis.toolchain.commons.cmxml.Point; import codemetropolis.toolchain.rendering.model.BasicBlock; public class Banner implements Primitive { - + public enum Orientation { - SOUTH(0), - SOUTHWEST(2), - WEST(4), - NORTHWEST(6), - NORTH(8), - NORTHEAST(10), - EAST(12), - SOUTHEAST(14); - + SOUTH(0), SOUTHWEST(2), WEST(4), NORTHWEST(6), NORTH(8), NORTHEAST(10), EAST(12), SOUTHEAST(14); + private final int value; - + Orientation(int v) { value = v; } - + public int getValue() { return value; } } - + private Point position; private Orientation orientation; - private String color; public Banner(int x, int y, int z, Orientation orientation, String color) { super(); this.position = new Point(x, y, z); this.orientation = orientation; - this.color = color; } - + @Override public int toCSVFile(File directory) { - new Boxel(new BasicBlock((short) 176, orientation.getValue()), position, color).toCSVFile(directory); + + Map properties = new HashMap<>(); + properties.put("facing", orientation.getValue() + ""); + + BasicBlock banner = new BasicBlock(BasicBlock.BANNER.getId(), properties); + + new Boxel(banner, position).toCSVFile(directory); return 1; } + @Override public int getNumberOfBlocks() { return 1; } - + } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Boxel.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Boxel.java index 931fff2c..aa80e80d 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Boxel.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Boxel.java @@ -6,78 +6,99 @@ import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; - -import codemetropolis.blockmodifier.World; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.stream.Collectors; +//import codemetropolis.blockmodifier.World; +import codemetropolis.toolchain.rendering.control.World; import codemetropolis.toolchain.commons.cmxml.Point; import codemetropolis.toolchain.rendering.model.BasicBlock; public class Boxel implements Primitive { - + public BasicBlock block; public Point position; public String info; - + public Boxel(BasicBlock block, Point position) { super(); this.block = block; this.position = position; } - + public Boxel(BasicBlock block, Point position, String info) { this(block, position); this.info = info; + } - + public void render(World world) { - if(position.getY() < 0 || position.getY() >= 255) return; - - switch(block.getId()) { - case 63: - world.setSignPost(position.getX(), position.getY(), position.getZ(), block.getData(), info); - break; - case 68: - world.setWallSign(position.getX(), position.getY(), position.getZ(), block.getData(), info); - break; - case 176: - world.setBanner(position.getX(), position.getY(), position.getZ(), block.getData(), World.BannerColor.valueOf(info.toUpperCase())); - break; - default: - world.setBlock(position.getX(), position.getY(), position.getZ(), block.getId(), block.getData()); + if (position.getY() < 0 || position.getY() >= 255) + return; + + switch (block.getId()) { + + case "minecraft:sign": + world.setSignPost(position.getX(), position.getY(), position.getZ(), block.getProperties(), info); + break; + case "minecraft:wall_sign": + world.setWallSign(position.getX(), position.getY(), position.getZ(), block.getProperties(), info); + break; + case "minecraft:white_banner": + world.setBanner(position.getX(), position.getY(), position.getZ(), block.getProperties(), + World.BannerColor.valueOf(info.toUpperCase())); + break; + case "minecraft:crafting_table": + world.setMob(position.getX(), position.getY(), position.getZ(), block.getId()); + break; + default: + world.setBlock(position.getX(), position.getY(), position.getZ(), block.getId(), block.getProperties()); } } - + public String toCSV() { - //if(block == BasicBlock.NonBlock) return null; - if(block.getId() == -1) return null; - return String.format("%d;%d;%d;%d;%d;%s", block.getId(), block.getData(), position.getX(), position.getY(), position.getZ(), (info == null || info.equals("") ? "NULL" : info)); + + if (block.getId().equals("")) { + return null; + } + + String fancyProperties = block.getProperties().entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()) + .collect(Collectors.joining("&")); + + return String.format("%s;%s;%d;%d;%d;%s", block.getId(), fancyProperties, position.getX(), position.getY(), + position.getZ(), (info == null || info.equals("") ? "NULL" : info)); } - + public static Boxel parseCSV(String csv) { String[] parts = csv.split(";"); - return new Boxel( - new BasicBlock( - Short.parseShort(parts[0]), - Integer.parseInt(parts[1])), - new Point( - Integer.parseInt(parts[2]), - Integer.parseInt(parts[3]), - Integer.parseInt(parts[4])), - (parts[5].equals("NULL") ? "" : parts[5]) - ); + Map properties = Collections.emptyMap(); + try { + String[] rawProperties = parts[1].split("&"); + properties = Arrays.stream(rawProperties) + .collect(Collectors.toMap(e -> e.split("=")[0], e -> e.split("=")[1])); + } catch (Exception e2) { + + } + + return new Boxel(new BasicBlock(parts[0], properties), + new Point(Integer.parseInt(parts[2]), Integer.parseInt(parts[3]), Integer.parseInt(parts[4])), + (parts[5].equals("NULL") ? "" : parts[5])); } - + @Override public int toCSVFile(File directory) { int x = position.getX() >> 9; int z = position.getZ() >> 9; - + directory.mkdirs(); String filename = String.format("blocks.%d.%d.csv", x, z); File file = new File(directory, filename); - - try(PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(file, true)))) { + + try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(file, true)))) { String csv = toCSV(); - if(csv != null) writer.println(csv); + if (csv != null) + writer.println(csv); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e1) { @@ -91,4 +112,48 @@ public int getNumberOfBlocks() { return 1; } + @Override + public String toString() { + return "Boxel [block=" + block + ", position=" + position + ", info=" + info + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((block == null) ? 0 : block.hashCode()); + result = prime * result + ((info == null) ? 0 : info.hashCode()); + result = prime * result + ((position == null) ? 0 : position.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Boxel other = (Boxel) obj; + if (block == null) { + if (other.block != null) + return false; + } else if (!block.equals(other.block)) + return false; + if (info == null) { + if (other.info != null) + return false; + } else if (!info.equals(other.info)) + return false; + if (position == null) { + if (other.position != null) + return false; + } else if (!position.equals(other.position)) + return false; + return true; + } + + + } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Door.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Door.java index ca210c5f..eb458ec2 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Door.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Door.java @@ -1,29 +1,18 @@ package codemetropolis.toolchain.rendering.model.primitive; import java.io.File; +import java.util.HashMap; +import java.util.Map; import codemetropolis.toolchain.commons.cmxml.Point; import codemetropolis.toolchain.rendering.model.BasicBlock; public class Door implements Primitive { - + public enum Orientation { - NORTH(1), - SOUTH(3), - WEST(0), - EAST(2); - - private final int value; - - Orientation(int v) { - value = v; - } - - public int getValue() { - return value; - } + SOUTH, NORTH, EAST, WEST; } - + private Point position; private Orientation orientation; @@ -32,16 +21,42 @@ public Door(int x, int y, int z, Orientation orientation) { this.position = new Point(x, y, z); this.orientation = orientation; } - + @Override public int toCSVFile(File directory) { - new Boxel(new BasicBlock((short) 64, orientation.getValue()), position).toCSVFile(directory); - new Boxel(new BasicBlock((short) 64, 8), new Point(position.getX(), position.getY() + 1, position.getZ())).toCSVFile(directory); + Map upperDoorProperties = new HashMap<>(); + upperDoorProperties.put("facing", getOppositeOrientation().toString().toLowerCase()); + upperDoorProperties.put("half", "upper"); + + Map lowerDoorProperties = new HashMap<>(); + lowerDoorProperties.put("facing", getOppositeOrientation().toString().toLowerCase()); + lowerDoorProperties.put("half", "lower"); + + BasicBlock upperDoor = new BasicBlock(BasicBlock.DOOR.getId(), upperDoorProperties); + BasicBlock lowerDoor = new BasicBlock(BasicBlock.DOOR.getId(), lowerDoorProperties); + + new Boxel(lowerDoor, position).toCSVFile(directory); + new Boxel(upperDoor, new Point(position.getX(), position.getY() + 1, position.getZ())).toCSVFile(directory); return 2; } + @Override public int getNumberOfBlocks() { return 2; } - + + private Orientation getOppositeOrientation() { + switch (orientation) { + case NORTH: + return Orientation.SOUTH; + case SOUTH: + return Orientation.NORTH; + case WEST: + return Orientation.EAST; + case EAST: + return Orientation.WEST; + default: + return null; + } + } } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Mob.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Mob.java new file mode 100644 index 00000000..114c1d12 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Mob.java @@ -0,0 +1,30 @@ +package codemetropolis.toolchain.rendering.model.primitive; + +import codemetropolis.toolchain.commons.cmxml.Point; +import codemetropolis.toolchain.rendering.model.BasicBlock; + +import java.io.File; + + +public class Mob implements Primitive{ + + public static final String[] SupportedMobs = {"pig"}; + + private Point position; + private String name; + + public Mob(int x, int y, int z, String name){ + super(); + this.position = new Point(x, y, z); + this.name = name; + } + + @Override + public int toCSVFile(File directory){ + new Boxel(new BasicBlock(BasicBlock.Mob), position, name).toCSVFile(directory); + return 1; + } + + @Override + public int getNumberOfBlocks(){ return 1; } +} diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Row.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Row.java index 2bbc9760..f69d5033 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Row.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Row.java @@ -1,7 +1,6 @@ package codemetropolis.toolchain.rendering.model.primitive; import java.io.File; - import codemetropolis.toolchain.commons.cmxml.Point; import codemetropolis.toolchain.rendering.model.BasicBlock; @@ -16,23 +15,44 @@ public enum Direction { EAST; } + public enum BlockFacing { + NONE, + NORTH, + SOUTH, + WEST, + EAST; + + } + private Point position; private int length; private Direction orientation; private BasicBlock[] pattern; + private BlockFacing facing; - public Row(Point position, int length, Direction orientation, BasicBlock[] pattern) { + public Row(Point position, int length, Direction orientation, BasicBlock[] pattern, BlockFacing facing) { super(); + this.facing = facing; this.position = position; this.length = length; this.orientation = orientation; this.pattern = pattern; } + public Row(Point position, int length, Direction orientation, BasicBlock[] pattern) { + this(position, length, orientation, pattern, BlockFacing.NONE); + } + @Override public int toCSVFile(File directory) { int c = 0; for(int i = 0; i < length; i++) { + + BasicBlock block = new BasicBlock(pattern[c]); + if(facing != BlockFacing.NONE) { + block.getProperties().put("facing", facing.toString().toLowerCase()); + } + Point blockPos = null; switch(orientation) { case UP: @@ -55,7 +75,7 @@ public int toCSVFile(File directory) { break; } - new Boxel(pattern[c], blockPos).toCSVFile(directory); + new Boxel(block, blockPos).toCSVFile(directory); if(++c > pattern.length - 1) c = 0; } return length; diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/SignPost.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/SignPost.java index ad90f5e1..90d9ad39 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/SignPost.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/SignPost.java @@ -1,33 +1,28 @@ package codemetropolis.toolchain.rendering.model.primitive; import java.io.File; +import java.util.HashMap; +import java.util.Map; import codemetropolis.toolchain.commons.cmxml.Point; import codemetropolis.toolchain.rendering.model.BasicBlock; public class SignPost implements Primitive { - + public enum Orientation { - SOUTH(0), - SOUTHWEST(2), - WEST(4), - NORTHWEST(6), - NORTH(8), - NORTHEAST(10), - EAST(12), - SOUTHEAST(14); - + SOUTH(0), SOUTHWEST(2), WEST(4), NORTHWEST(6), NORTH(8), NORTHEAST(10), EAST(12), SOUTHEAST(14); + private final int value; - + Orientation(int v) { value = v; } - + public int getValue() { return value; } } - + private Point position; private Orientation orientation; private String text; @@ -38,15 +33,22 @@ public SignPost(int x, int y, int z, Orientation orientation, String text) { this.orientation = orientation; this.text = text; } - + @Override public int toCSVFile(File directory) { - new Boxel(new BasicBlock((short) 63, orientation.getValue()), position, text).toCSVFile(directory); + + Map properties = new HashMap<>(); + properties.put("rotation", orientation.getValue() + ""); + + BasicBlock signPost = new BasicBlock(BasicBlock.SIGN.getId(), properties); + + new Boxel(signPost, position, text).toCSVFile(directory); return 1; } + @Override public int getNumberOfBlocks() { return 1; } - + } diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/SolidBox.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/SolidBox.java index 46729449..102d75c9 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/SolidBox.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/SolidBox.java @@ -21,7 +21,7 @@ public SolidBox(Point basePoint, Point size, Pattern fill, Pattern stroke, Orien this.orientation = orientation; } - private Point flipPattern(Point original, Point size) { + protected Point flipPattern(Point original, Point size) { switch ( orientation ) { case NearX: return original; diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Spawner.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Spawner.java new file mode 100644 index 00000000..f2ad9370 --- /dev/null +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/Spawner.java @@ -0,0 +1,27 @@ +package codemetropolis.toolchain.rendering.model.primitive; + +import java.io.File; + +import codemetropolis.toolchain.commons.cmxml.Point; +import codemetropolis.toolchain.rendering.model.BasicBlock; + +public class Spawner implements Primitive { + + private Point position; + + public Spawner(int x, int y, int z) { + super(); + this.position = new Point(x, y, z); + } + + @Override + public int toCSVFile(File directory) { + new Boxel(new BasicBlock("minecraft:spawner"), position).toCSVFile(directory); + return 1; + } + @Override + public int getNumberOfBlocks() { + return 1; + } + +} diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/WallSign.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/WallSign.java index 4c9b8921..ab43ebd7 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/WallSign.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/model/primitive/WallSign.java @@ -1,6 +1,8 @@ package codemetropolis.toolchain.rendering.model.primitive; import java.io.File; +import java.util.HashMap; +import java.util.Map; import codemetropolis.toolchain.commons.cmxml.Point; import codemetropolis.toolchain.rendering.model.BasicBlock; @@ -8,20 +10,10 @@ public class WallSign implements Primitive { public enum Orientation { - NORTH(2), - SOUTH(3), - WEST(4), - EAST(5); - - private final int value; - - Orientation(int v) { - value = v; - } - - public int getValue() { - return value; - } + NORTH, + SOUTH, + WEST, + EAST; } private Point position; @@ -41,7 +33,14 @@ public WallSign(Point position, Orientation orientation, String text) { @Override public int toCSVFile(File directory) { - new Boxel(new BasicBlock((short) 68, orientation.getValue()), position, text).toCSVFile(directory); + + Map properties = new HashMap<>(); + properties.put("facing", orientation.toString().toLowerCase()); + + BasicBlock wallSign = new BasicBlock(BasicBlock.WALL_SIGN.getId(), properties); + + + new Boxel(wallSign, position, text).toCSVFile(directory); return 1; } @Override diff --git a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/util/Character.java b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/util/Character.java index 6dab99fd..69fc4343 100644 --- a/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/util/Character.java +++ b/sources/toolchain/rendering/src/main/java/codemetropolis/toolchain/rendering/util/Character.java @@ -28,39 +28,42 @@ public enum Character { public static Character parse(String str) { for(Character c : Character.values()) { + System.out.println(c); if(c.toString().equalsIgnoreCase(str)) return c; } return Character.UNDEFINED; } - public BasicBlock getBlock() { + public BasicBlock getBlock() throws Exception { + + switch(this) { + case GLASS: return new BasicBlock( "minecraft:glass" ); + case METAL: return new BasicBlock( "minecraft:iron_block" ); case STONE: return new BasicBlock( "minecraft:stone" ); case COBBLESTONE: return new BasicBlock( "minecraft:cobblestone" ); case MOSSY_STONE: return new BasicBlock( "minecraft:mossy_cobblestone" ); case SANDSTONE: return new BasicBlock( "minecraft:sandstone" ); case OBSIDIAN: return new BasicBlock( "minecraft:obsidian" ); case WOOD: return new BasicBlock( "minecraft:log" ); - case DARK_WOOD: return new BasicBlock( "minecraft:log", 1 ); - case BIRCH_WOOD: return new BasicBlock( "minecraft:log", 2 ); + case DARK_WOOD: return new BasicBlock( "minecraft:log"); + case BIRCH_WOOD: return new BasicBlock( "minecraft:log"); case PLANKS: return new BasicBlock( "minecraft:planks" ); - case DARK_PLANKS: return new BasicBlock( "minecraft:planks", 5 ); - case METAL: return new BasicBlock( "minecraft:iron_block" ); + case DARK_PLANKS: return new BasicBlock( "minecraft:planks"); case DIRT: return new BasicBlock( "minecraft:dirt" ); - case SAND: return new BasicBlock( "minecraft:sandstone" , 2 ); + case SAND: return new BasicBlock( "minecraft:sandstone"); case RED_SAND: return new BasicBlock( "minecraft:sand" ); - case BRICK: return new BasicBlock( "minecraft:double_stone_slab", 4 ); - case STONE_BRICK: return new BasicBlock( "minecraft:double_stone_slab", 5 ); - case DARK_BRICK: return new BasicBlock( "minecraft:double_stone_slab", 6 ); - case GLASS: return new BasicBlock( "minecraft:glass" ); + case BRICK: return new BasicBlock( "minecraft:double_stone_slab"); + case STONE_BRICK: return new BasicBlock( "minecraft:double_stone_slab" ); + case DARK_BRICK: return new BasicBlock( "minecraft:double_stone_slab"); case GOLD: return new BasicBlock( "minecraft:gold_block" ); case DIAMOND: return new BasicBlock( "minecraft:diamond_block" ); - case UNDEFINED: return new BasicBlock( "minecraft:wool", 2 ); - default: return null; + case UNDEFINED: return new BasicBlock( "minecraft:wool" ); + default: throw new Exception("Unsupported Block"); } } - public BasicBlock getTopBlock() { + public BasicBlock getTopBlock() throws Exception { switch(this) { case WOOD: case DARK_WOOD: diff --git a/sources/toolchain/rendering/src/test/java/codemetropolis/toolchain/rendering/events/ProgressEventTest.java b/sources/toolchain/rendering/src/test/java/codemetropolis/toolchain/rendering/events/ProgressEventTest.java new file mode 100644 index 00000000..0d63fc44 --- /dev/null +++ b/sources/toolchain/rendering/src/test/java/codemetropolis/toolchain/rendering/events/ProgressEventTest.java @@ -0,0 +1,35 @@ +package codemetropolis.toolchain.rendering.events; + +import junit.framework.TestCase; + +public class ProgressEventTest extends TestCase { + + ProgressEvent testObj; + + public void setup() { + testObj = null; + } + + public void testGetPercent() { + testObj = new ProgressEvent(new Object(), null, 100, 200, 100); + assertEquals(50.0, testObj.getPercent()); + + testObj = new ProgressEvent(new Object(), null, 53, 56, 400); + assertEquals(94.64, testObj.getPercent(), 0.01); + + testObj = new ProgressEvent(new Object(), null, 30, 30, 1000); + assertEquals(100.0, testObj.getPercent()); + } + + public void testGetTimeLeftInMillis() { + testObj = new ProgressEvent(new Object(), null, 100, 200, 100); + assertEquals(100, testObj.getTimeLeftInMillis()); + + testObj = new ProgressEvent(new Object(), null, 53, 56, 400); + assertEquals(22, testObj.getTimeLeftInMillis()); + + testObj = new ProgressEvent(new Object(), null, 30, 30, 1000); + assertEquals(0, testObj.getTimeLeftInMillis()); + } + +} diff --git a/sources/toolchain/rendering/test/codemetropolis/toolchain/rendering/model/building/BridgeTest.java b/sources/toolchain/rendering/test/codemetropolis/toolchain/rendering/model/building/BridgeTest.java new file mode 100644 index 00000000..058b8c04 --- /dev/null +++ b/sources/toolchain/rendering/test/codemetropolis/toolchain/rendering/model/building/BridgeTest.java @@ -0,0 +1,71 @@ +package codemetropolis.toolchain.rendering.model.building; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +import org.junit.BeforeClass; +import org.junit.Test; + +import codemetropolis.toolchain.commons.cmxml.Buildable; +import codemetropolis.toolchain.commons.cmxml.Point; +import codemetropolis.toolchain.rendering.exceptions.RenderingException; + +/** Test class for {@link Bridge} for basic functions. + * + * @author Csuvik Viktor {@literal D1YZL5} + * @version %I% + * + */ + + +public class BridgeTest { + + private static Buildable parent; + private static Bridge bridge; + private static int BRIDGE_HEIGHT = 3; + private static int BRIDGE_WIDTH = 3; + + @BeforeClass + public static void setUpBeforeClass() { + + Buildable b = new Buildable( + "UNIQUE_ID", + "SAMPLE_BRIDGE", + Buildable.Type.BRIDGE, + new Point(0, 0, 0), + new Point(10, BRIDGE_HEIGHT, BRIDGE_WIDTH)); + + b.addAttribute(Linking.LINKING_ATTRIBUTE_TARGET, "TARGET_UNIQUE_ID"); + b.addAttribute(Linking.LINKING_ATTRIBUTE_STANDALONE, "false"); + b.addAttribute(Linking.LINKING_ATTRIBUTE_ORIENTATION, "south"); + + + parent = new Buildable( + "UNIQUE_ID2", + "SAMPLE_PARENT", + Buildable.Type.GARDEN, + new Point(0, 0, 0), + new Point(10, 10, 10) ); + + parent.addChild(b); + + + try { + bridge = new Bridge( b ); + } catch (RenderingException e) { + fail("Shouldn't throw exception."); + e.printStackTrace(); + } + + } + + @Test + public void testCalculatStepPosition() { + assertTrue( bridge.calculateStepPosition(true).getX() == bridge.innerBuildable.getPositionX() || + bridge.calculateStepPosition(true).getZ() == bridge.innerBuildable.getPositionZ()); + + assertFalse( bridge.calculateStepPosition(true).getX() == bridge.innerBuildable.getPositionX() && + bridge.calculateStepPosition(true).getZ() == bridge.innerBuildable.getPositionZ()); + } +} diff --git a/sources/toolchain/rendering/test/codemetropolis/toolchain/rendering/model/building/TunnelTest.java b/sources/toolchain/rendering/test/codemetropolis/toolchain/rendering/model/building/TunnelTest.java new file mode 100644 index 00000000..811984e4 --- /dev/null +++ b/sources/toolchain/rendering/test/codemetropolis/toolchain/rendering/model/building/TunnelTest.java @@ -0,0 +1,168 @@ +package codemetropolis.toolchain.rendering.model.building; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + +import codemetropolis.toolchain.commons.cmxml.Buildable; +import codemetropolis.toolchain.commons.cmxml.Point; +import codemetropolis.toolchain.rendering.control.WorldBuilder; +import codemetropolis.toolchain.rendering.exceptions.RenderingException; +import codemetropolis.toolchain.rendering.model.primitive.SolidBox; + + +/** Test class for {@link Tunnel} for basic functions. + * + * @author Csuvik Viktor {@literal D1YZL5} + * @version %I% + * + */ + + +public class TunnelTest { + + private static Buildable parent; + private static Tunnel tunnel; + private static int TUNNEL_HEIGHT = 3; + private static int TUNNEL_WIDTH = 3; + + @BeforeClass + public static void setUpBeforeClass() { + + Buildable b = new Buildable( + "UNIQUE_ID", + "SAMPLE_TUNNEL", + Buildable.Type.TUNNEL, + new Point(0, 0, 0), + new Point(10, TUNNEL_HEIGHT, TUNNEL_WIDTH)); + + b.addAttribute(Linking.LINKING_ATTRIBUTE_TARGET, "TARGET_UNIQUE_ID"); + b.addAttribute(Linking.LINKING_ATTRIBUTE_STANDALONE, "false"); + b.addAttribute(Linking.LINKING_ATTRIBUTE_ORIENTATION, "south"); + + parent = new Buildable( + "UNIQUE_ID2", + "SAMPLE_PARENT", + Buildable.Type.GARDEN, + new Point(0, 0, 0), + new Point(10, 10, 10) ); + + parent.addChild(b); + + + try { + tunnel = new Tunnel( b ); + } catch (RenderingException e) { + fail("Shouldn't throw exception."); + e.printStackTrace(); + } + + } + + @Test + public void testTunnelPosition() { + assertEquals(tunnel.getPosition().getX(), 0); + assertEquals(tunnel.getPosition().getY(), 0); + assertEquals(tunnel.getPosition().getZ(), 0); + } + + @Test + public void testTunnelSize() { + assertEquals(tunnel.getSize().getX(), 11); + assertEquals(tunnel.getSize().getY(), 3); + assertEquals(tunnel.getSize().getZ(), 3); + } + + @Test + public void testGetTarget() { + Buildable target = tunnel.getTarget(parent, "UNIQUE_ID"); + assertSame(target, tunnel.innerBuildable); + + target = tunnel.getTarget(parent, "NON_EXISTING_ID"); + assertNull(target); + + target = tunnel.getTarget(parent, parent.getId()); + assertSame(target, parent); + } + + @Test + public void testCalculateHeight() { + assertTrue(tunnel.calculateHeight(tunnel.innerBuildable) <= WorldBuilder.TUNNEL_LEVEL - TUNNEL_HEIGHT); + } + + @Test + public void testCalculatStepPosition() { + assertTrue( tunnel.calculateStepPosition(true).getX() == tunnel.innerBuildable.getPositionX() || + tunnel.calculateStepPosition(true).getZ() == tunnel.innerBuildable.getPositionZ()); + } + + @Test + public void testLampPositionY() { + SolidBox lampLine = tunnel.getLighting().get(0); + + int actual = lampLine.getBasePoint().getY(); + int expected = tunnel.level - 1; + assertEquals(expected, actual); + } + + @Test + public void testPrepareLightingReturnsValidList() { + List lighting = tunnel.prepareLighting(); + + assertNotNull(lighting); + + int expectedSize = 2; + int actualSize = lighting.size(); + assertEquals(expectedSize, actualSize); + } + + @Test + public void testPrepareLightingReturnsElementsNotNull() { + List lighting = tunnel.prepareLighting(); + + SolidBox lampLine = lighting.get(0); + assertNotNull(lampLine); + + SolidBox redstoneBlockLine = lighting.get(1); + assertNotNull(redstoneBlockLine); + } + + @Test + public void testPrepareLightningReturnsRightLampline() { + List lighting = tunnel.prepareLighting(); + SolidBox lampLine = lighting.get(0); + + int actualPositionY = lampLine.getBasePoint().getY(); + int expectedPositionY = tunnel.level - 1; + assertEquals(expectedPositionY, actualPositionY); + + int actualNBlocks = lampLine.getNumberOfBlocks(); + int expectedNBlocks = Math.abs((tunnel.getSize().getX()-2) * (tunnel.getSize().getY()-2) * (tunnel.getSize().getZ()-2)); + assertEquals(expectedNBlocks, actualNBlocks); + } + + @Test + public void testPrepareLightningReturnsRightRedstoneLine() { + List lighting = tunnel.prepareLighting(); + SolidBox redstoneLine = lighting.get(1); + + int actualPositionY = redstoneLine.getBasePoint().getY(); + int expectedPositionY = tunnel.level - 2; + assertEquals(expectedPositionY, actualPositionY); + + int actualNBlocks = redstoneLine.getNumberOfBlocks(); + int expectedNBlocks = Math.abs((tunnel.getSize().getX()-2) * (tunnel.getSize().getY()-2) * (tunnel.getSize().getZ()-2)); + assertEquals(expectedNBlocks, actualNBlocks); + } + +} + diff --git a/sources/toolchain/rendering/test/codemetropolis/toolchain/rendering/model/primitive/SolidBoxTest.java b/sources/toolchain/rendering/test/codemetropolis/toolchain/rendering/model/primitive/SolidBoxTest.java new file mode 100644 index 00000000..f90daf85 --- /dev/null +++ b/sources/toolchain/rendering/test/codemetropolis/toolchain/rendering/model/primitive/SolidBoxTest.java @@ -0,0 +1,28 @@ +package codemetropolis.toolchain.rendering.model.primitive; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; +import codemetropolis.toolchain.commons.cmxml.Point; +import codemetropolis.toolchain.rendering.model.BasicBlock; +import codemetropolis.toolchain.rendering.model.pattern.RepeationPattern; +import codemetropolis.toolchain.rendering.util.Orientation; + +public class SolidBoxTest { + + SolidBox solidBox; + + @Test + public void testGetNumberOfBlocks() { + solidBox = new SolidBox( + new Point(0, 0, 0), + new Point(2, 2, 2), + new RepeationPattern( new BasicBlock[][][]{ { { new BasicBlock( "minecraft:air" ), } } } ), + new RepeationPattern( new BasicBlock[][][]{ { { new BasicBlock( "minecraft:air" ), } } } ), + Orientation.NearX); + int expected = 8; + int actual = solidBox.getNumberOfBlocks(); + assertEquals(expected, actual); + } + +} +