blob: e0363c1c75b38a7e96fb0b82f94ef0a4ed9156db [file] [log] [blame]
gobrien1a8e02f2008-01-30 01:46:26 +00001<?php
2/*******************************************************************************
3 * Copyright (c) 2008 Eclipse Foundation and others.
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Eclipse Foundation - Initial API and implementation
droy133e7462008-05-13 17:37:24 +000011 * Motoki MORT mori-m@mxa.nes.nec.co.jp - patch, bug 227366
gobrien1a8e02f2008-01-30 01:46:26 +000012*******************************************************************************/
13
14/*
15 * Documentation: http://wiki.eclipse.org/Babel_/_Server_Tool_Specification#Outputs
16 */
17//TODO handle versions, however that works; files.version is like "3.4" for Eclipse 3.4
18
19/*
20 * Globals
21 */
gobrienb854dcb2008-01-30 18:50:45 +000022ob_start();
23
24
25if(defined('BABEL_BASE_DIR')){
26 require(BABEL_BASE_DIR . "classes/system/dbconnection.class.php");
27}else{
28 define('BABEL_BASE_DIR', "../../");
29 require(BABEL_BASE_DIR . "classes/system/dbconnection.class.php");
30}
31
droy86f26212008-03-04 19:54:23 +000032if( !function_exists('json_encode') ){
33 require("/home/data/httpd/babel.eclipse.org/html/json_encode.php");
34 function json_encode($encode){
35 $jsons = new Services_JSON();
36 return $jsons->encode($encode);
37 }
38}
39
gobrienb854dcb2008-01-30 18:50:45 +000040if (!($ini = @parse_ini_file(BABEL_BASE_DIR . 'classes/base.conf'))) {
41 errorLog("Failed to find/read database conf file - aborting.");
42 exitTo("error.php?errNo=101300","error: 101300 - database conf can not be found");
43}
44
45$context = $ini['context'];
46if($context == "") {
47 $context = "staging";
48}
49global $context;
50
51
52$base_out_dir = "/home/babel-working/";
53
54if(!file_exists($base_out_dir)){
55 $base_out_dir = "";
56}
57
58if($context == "live"){
59 $base_out_dir .= "live/";
60}else{
61 $base_out_dir .= "staging/";
62}
63if( !file_exists( $base_out_dir ) ) {
64 exec( "mkdir $base_out_dir" );
65}
66
67$temporary_dir = $base_out_dir."tmp_generated/";
gobrien431ca4f2008-01-30 19:54:00 +000068$staging_update_site = $base_out_dir."output/";
gobriene2bb07b2008-01-30 19:00:42 +000069$source_files_for_generate = "source_files_for_generate/";
gobrien1a8e02f2008-01-30 01:46:26 +000070
71$leader1 = "";
72$leader1S= "";
73$leader = ". . ";
74$leaderS= ". . ";
75$generated_timestamp = date("Ymdhis");
76
droy0b08d292008-05-28 15:18:11 +000077
gobrien1a8e02f2008-01-30 01:46:26 +000078/*
79 * Get the data (plugins, files, translations) from the live database
80 */
gobrien08a4e4e2008-01-30 18:18:29 +000081
gobrien08a4e4e2008-01-30 18:18:29 +000082$dbc = new DBConnection();
83global $dbh;
84$dbh = $dbc->connect();
85
gobrien1a8e02f2008-01-30 01:46:26 +000086
87/*
droy0b08d292008-05-28 15:18:11 +000088 * Generate one update site pack per train
gobrien1a8e02f2008-01-30 01:46:26 +000089 */
90$site_xml = '';
droy0b08d292008-05-28 15:18:11 +000091$train_result = mysql_query( 'SELECT * FROM release_train_projects' );
92while( ($train_row = mysql_fetch_assoc($train_result)) != null ) {
93 $train_id = $train_row['train_id'];
94 $project_id = $language_row['project_id'];
95 $version = $language_row['version'];
gobrien1a8e02f2008-01-30 01:46:26 +000096
droy0b08d292008-05-28 15:18:11 +000097
gobrien1a8e02f2008-01-30 01:46:26 +000098 /*
droy0b08d292008-05-28 15:18:11 +000099 * Clear the staging site
gobrien1a8e02f2008-01-30 01:46:26 +0000100 */
droy0b08d292008-05-28 15:18:11 +0000101
102 # output/europa/plugins
103 # output/ganymede/plugins
104 # etc...
105 $staging_update_site .= $train_row['train_id'] . "/";
106
107 if( file_exists( $staging_update_site ) ) {
108 exec( "rm -rf $staging_update_site*" );
109 } else {
110 exec( "mkdir $staging_update_site" );
111 }
112 if( file_exists( "${staging_update_site}plugins/" ) ) {
113 exec( "rm -rf ${staging_update_site}plugins/*" );
114 } else {
115 exec( "mkdir ${staging_update_site}plugins/" );
116 }
117 if( file_exists( "${staging_update_site}features/" ) ) {
118 exec( "rm -rf ${staging_update_site}features/*" );
119 } else {
120 exec( "mkdir ${staging_update_site}features/" );
121 }
122
123 /*
124 * Generate one language pack per language
125 */
droy64eca802008-03-10 19:49:21 +0000126
droy0b08d292008-05-28 15:18:11 +0000127 $language_result = mysql_query( 'SELECT * FROM languages WHERE languages.is_active' );
128 while( ($language_row = mysql_fetch_assoc($language_result)) != null ) {
129 $language_name = $language_row['name'];
130 $language_iso = $language_row['iso_code'];
131 $language_locale = $language_row['locale'];
132 if ( $language_locale != null ) {
133 $language_name = $language_locale . " " . $language_name;
gobrien1a8e02f2008-01-30 01:46:26 +0000134 }
droy0b08d292008-05-28 15:18:11 +0000135 echo "${leader1}Generating language pack for $train_id - $language_name ($language_iso)(" . $language_row['language_id'] . ")\n";
136
gobrien1a8e02f2008-01-30 01:46:26 +0000137 /*
droy0b08d292008-05-28 15:18:11 +0000138 * Determine which plug-ins need to be in this language pack.
gobrien1a8e02f2008-01-30 01:46:26 +0000139 */
droy0b08d292008-05-28 15:18:11 +0000140 $file_result = mysql_query( "SELECT DISTINCT
141 f.file_id, f.name
142FROM files AS f
143 INNER JOIN strings AS s ON f.file_id = s.file_id
144 INNER JOIN translations AS t on (s.string_id = t.string_id AND t.is_active)
145 INNER JOIN release_train_projects as v on (f.project_id = v.project_id AND f.version = v.version)
146WHERE
147 t.language_id = " . $language_row['language_id'] . "
148 AND f.is_active
droy3725f7c2008-05-28 15:21:48 +0000149 AND v.train_id = '" . $train_row['train_id'] . "'");
droy0b08d292008-05-28 15:18:11 +0000150 $plugins = array();
151 while( ($file_row = mysql_fetch_assoc($file_result)) != null ) {
152 # strip source folder (bug 221675)
153 $pattern = '/^([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)\.(.*)\/(.*)\/(\1)\/(\2)\/(.*)\.properties$/i';
154 $replace = '${1}.${2}.${3}/${5}/${6}/${7}.properties';
155 $file_row['name'] = preg_replace($pattern, $replace, $file_row['name']);
156
157 if( preg_match( "/^([a-zA-Z0-9\.]+)\/(.*)$/", $file_row['name'], $matches ) ) {
158 $file_row['subname'] = $matches[2];
159 $plugins[$matches[1]][] = $file_row;
160 } else {
161 echo " WARNING: no plug-in name found in file " . $file_row['file_id'] . " \"" . $file_row['name'] . "\"\n";
gobrien1a8e02f2008-01-30 01:46:26 +0000162 }
droy0b08d292008-05-28 15:18:11 +0000163 }
164 /*
165 * Generate one plug-in fragment for each plug-in
166 */
167 foreach ($plugins as $plugin_name => $plugin_row ) {
168 echo "${leader1}${leader}Generating plug-in fragment $plugin_name \n";
gobrien1a8e02f2008-01-30 01:46:26 +0000169 /*
droy0b08d292008-05-28 15:18:11 +0000170 * Clean and create the temporary directory
gobrien1a8e02f2008-01-30 01:46:26 +0000171 */
droy0b08d292008-05-28 15:18:11 +0000172 if ( file_exists( $temporary_dir ) ) {
173 exec( "rm -rf $temporary_dir; mkdir $temporary_dir" );
174 } else {
175 exec( "mkdir $temporary_dir" );
176 }
177
gobrien1a8e02f2008-01-30 01:46:26 +0000178 /*
droy0b08d292008-05-28 15:18:11 +0000179 * Generate each *.properties file
gobrien1a8e02f2008-01-30 01:46:26 +0000180 */
droy0b08d292008-05-28 15:18:11 +0000181 foreach ($plugin_row as $properties_file) {
182 /*
183 * Convert the filename to *_lang.properties, e.g., foo_fr.properties
184 */
185 $filename = $properties_file['subname'];
186 if( preg_match( "/^(.*)\.properties$/", $filename, $matches ) ) {
187 $filename = $matches[1] . '_' . $language_iso . '.properties';
gobrien1a8e02f2008-01-30 01:46:26 +0000188 }
droy0b08d292008-05-28 15:18:11 +0000189 echo "${leader1}${leader}${leader}Generating properties file $filename (" . $properties_file['file_id'] . ")\n";
190 /*
191 * Create any needed sub-directories
192 */
193 $fullpath = $temporary_dir . $filename;
194 preg_match( "/^((.*)\/)?(.+?)$/", $fullpath, $matches );
195 exec( "mkdir -p \"" . $matches[1] . "\"");
196 /*
197 * Start writing to the file
198 */
199 $outp = fopen( $fullpath, "w" );
200 fwrite( $outp, "# Copyright by many contributors; see http://babel.eclipse.org/\n" );
201 //TODO correct copyrights from all contributors
202 /*
203 * For each string that is translated in this file, write it out
204 * Note that if a string is not translated, then it will not be
205 * included and thus Eclipse will pick up the default string for
206 * that key from the default *.properities file. Thus we only
207 * include the strings that are translated.
208 */
209 $sql = "
210 SELECT
211 strings.name AS `key`,
212 strings.value AS orig,
213 translations.value AS trans
214 FROM strings, translations
215 WHERE strings.string_id = translations.string_id
216 AND translations.language_id = " . $language_row['language_id'] . "
217 AND strings.file_id = " . $properties_file['file_id'] . "
218 AND translations.is_active
219 ";
220 $strings_result = mysql_query( $sql );
221 while( ($strings_row = mysql_fetch_assoc($strings_result)) != null ) {
222 fwrite( $outp, $strings_row['key'] . "=" );
223 #echo "${leader1S}${leaderS}${leaderS}${leaderS}" . $strings_row['key'] . "=";
224 if( $strings_row['trans'] ) {
225 # json_encode returns the string with quotes fore and aft. Need to strip them.
226 $tr_string = preg_replace('/^"(.*)"$/', '${1}', json_encode($strings_row['trans']));
227 $tr_string = str_replace('\\\\', '\\', $tr_string);
228 fwrite( $outp, $tr_string );
229 # echo $strings_row['trans'];
230 } else {
231 fwrite( $outp, $strings_row['orig'] );
232 }
233 fwrite( $outp, "\n" );
234 # echo "\n";
235 }
236 /*
237 * Finish the properties file
238 */
239 fclose( $outp );
240 echo "${leader1}${leader}${leader}completed properties file $filename\n";
gobrien1a8e02f2008-01-30 01:46:26 +0000241 }
242 /*
droy0b08d292008-05-28 15:18:11 +0000243 * Copy in the various legal files
gobrien1a8e02f2008-01-30 01:46:26 +0000244 */
droy0b08d292008-05-28 15:18:11 +0000245 exec( "cp ${source_files_for_generate}about.html ${temporary_dir}" );
246 exec( "cp ${source_files_for_generate}license.html ${temporary_dir}" );
247 exec( "cp ${source_files_for_generate}epl-v10.html ${temporary_dir}" );
248 exec( "cp ${source_files_for_generate}eclipse_update_120.jpg ${temporary_dir}" );
249 /*
250 * Generate the META-INF/MANIFEST.MF file
251 */
252 $parent_plugin_id = $plugin_name;
253 $fragment_id = "${parent_plugin_id}.nl_$language_iso";
254 $fragment_major_version = "0.2.0"; //TODO what version number should these plugins be?
255 $fragment_version = $fragment_major_version . ".v" . $generated_timestamp;
256 $fragment_filename = $fragment_id . "_" . $fragment_version . ".jar";
257 $parent_min_version = "0.0.0"; //TODO specify a min version (when versions are supported)
258 $parent_max_version = "9.9.9"; //TODO specify a max version (when versions are supported)
259
260 $plugins[$plugin_name]['id'] = $fragment_id;
261 $plugins[$plugin_name]['version'] = $fragment_version;
262
263 exec( "mkdir $temporary_dir/META-INF" );
264 $outp = fopen( "$temporary_dir/META-INF/MANIFEST.MF", "w" );
265 fwrite( $outp, "Manifest-Version: 1.0\n");
266 fwrite( $outp, "Bundle-Name: $parent_plugin_id $language_name NLS Support\n");
267 fwrite( $outp, "Bundle-SymbolicName: $fragment_id ;singleton=true\n");
268 fwrite( $outp, "Bundle-Version: $fragment_version\n");
269 fwrite( $outp, "Bundle-Vendor: Eclipse Foundation Inc.\n");
270 fwrite( $outp, "Fragment-Host: $parent_plugin_id;bundle-version=\"[$parent_min_version,$parent_max_version)\"\n");
gobrien1a8e02f2008-01-30 01:46:26 +0000271 fclose( $outp );
droy0b08d292008-05-28 15:18:11 +0000272 /*
273 * Jar up this directory as the fragment plug-in jar
274 */
275 system( "cd $temporary_dir; jar cfM ${staging_update_site}plugins/$fragment_filename ." );
276 echo "${leader1}${leader}completed plug-in fragment $plugin_name\n";
gobrien1a8e02f2008-01-30 01:46:26 +0000277 }
droy0b08d292008-05-28 15:18:11 +0000278 /*
279 * Clean and create the temporary directory
280 */
281 if ( file_exists( $temporary_dir ) ) {
282 exec( "rm -rf $temporary_dir; mkdir $temporary_dir" );
283 } else {
284 exec( "mkdir $temporary_dir" );
285 }
gobrien1a8e02f2008-01-30 01:46:26 +0000286 /*
droy0b08d292008-05-28 15:18:11 +0000287 * Create the feature.xml
288 *
289 * TODO <url><update label=... url=... and <url><discovery label=... url=... are not implemented
290 *
291 * <url>
292 * <update label="%updateSiteName" url="http://update.eclipse.org/updates/3.2" />
293 * <discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.2" />
294 * </url>
gobrien1a8e02f2008-01-30 01:46:26 +0000295 */
droy0b08d292008-05-28 15:18:11 +0000296 $feature_id = "org.eclipse.nls.$language_iso";
297 $feature_major_version = "0.2.0"; //TODO what version number should this feature be?
298 $feature_version = $feature_major_version . ".v" . $generated_timestamp;
299 $feature_filename = $feature_id . "_" . $feature_version . ".jar";
300
301 $outp = fopen( "$temporary_dir/feature.xml", "w" );
302 fwrite( $outp, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
303 <feature
304 id=\"$feature_id\"
305 label=\"Eclipse Language Pack for $language_name\"
306 image=\"eclipse_update_120.jpg\"
307 provider-name=\"Eclipse Foundation Inc.\"
308 version=\"$feature_version\">
309 <license url=\"license.html\">"
310 . htmlspecialchars( file_get_contents( "${source_files_for_generate}license.txt" ) ) . "</license>
311 <description>Translations in $language_name for all Eclipse Projects</description>
312 " );
313 foreach ($plugins as $plugin_name => $plugin_row ) {
314 fwrite( $outp, '<plugin fragment="true" id="'
315 . $plugin_row['id'] . '" unpack="false" version="'
316 . $plugin_row['version'] . '"/>
317 ' );
318 }
319 fwrite( $outp, '</feature>
320 ' );
gobrien1a8e02f2008-01-30 01:46:26 +0000321 fclose( $outp );
droy0b08d292008-05-28 15:18:11 +0000322 /*
323 * Jar up this directory as the feature jar
324 */
325 system( "cd $temporary_dir; jar cfM ${staging_update_site}features/$feature_filename ." );
gobrien1a8e02f2008-01-30 01:46:26 +0000326 /*
droy0b08d292008-05-28 15:18:11 +0000327 * Register this feature with the site.xml
gobrien1a8e02f2008-01-30 01:46:26 +0000328 */
droy0b08d292008-05-28 15:18:11 +0000329 $site_xml .= "<feature url=\"features/$feature_filename\" id=\"$feature_id\" version=\"$feature_version\">
330 <category name=\"Language Packs\"/></feature>
331 ";
332 echo "${leader1}completed language pack for $language_name ($language_iso)\n";
gobrien1a8e02f2008-01-30 01:46:26 +0000333 }
gobrien1a8e02f2008-01-30 01:46:26 +0000334 /*
droy0b08d292008-05-28 15:18:11 +0000335 * <site mirrorsURL=... implemented in the weekly build process by sed'ing <site>
gobrien1a8e02f2008-01-30 01:46:26 +0000336 */
droy0b08d292008-05-28 15:18:11 +0000337 $outp = fopen( "${staging_update_site}site.xml", "w" );
338 fwrite( $outp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
339 <site>
340 <description url=\"http://babel.eclipse.org/\">This update site contains
341 user-contributed translations of the strings in all Eclipse projects. Please
342 see the http://babel.eclipse.org/ Babel project web pages for a full how-to-use
343 explanation of these translations as well as how you can contribute to
344 the translations of this and future versions of Eclipse.</description>
345 <category-def name=\"Language Packs\" label=\"Language Packs\">
346 <description>Language packs for all Eclipse projects</description>
347 </category-def>
348 " );
349 fwrite( $outp, $site_xml );
350 fwrite( $outp, "</site>
351 " );
gobrien1a8e02f2008-01-30 01:46:26 +0000352 fclose( $outp );
gobrien1a8e02f2008-01-30 01:46:26 +0000353}
gobrien1a8e02f2008-01-30 01:46:26 +0000354echo "Completed generating update site\n";
355
356/*
3572. what happens if the translation feature includes plug-in fragments for
358 plug-ins that are not in the current image?
359 does it load correctly and ignore those fragments? if so, good
360 A: warnings appear in the run-time error log
361 does it fail to load? if so, then we need to generate different features, perhaps
362 one feature for each plug or else we need to know more about the project
363 distro structure to know which plug-ins to put in each feature
364 what happens if those plug-ins are later added - does it load the strings now?
365 A: probably not
3663. need to handle different versions of each feature/plugin/platform; generate different
367 language packs for each
368*/
369
gobrienb854dcb2008-01-30 18:50:45 +0000370$alloutput = fopen($base_out_dir."langpack_output_".date("m_d_Y"), "w" );
371fwrite( $alloutput,ob_get_contents());
372?>