java2js.js

#!/usr/bin/env node import fs from 'fs'; import path from 'path'; const ARRAY_ALIASES = { table: ['tableLists'], src: ['srcColLists'], dest: ['destColLists', 'destColList'], type: ['typeLists'], tableHash: ['tableLists_hash'], srcHash: ['srcColLists_hash'], destHash: ['destColLists_hash', 'destColList_hash'], typeHash: ['typeLists_hash'] }; function printUsage() { console.log([ 'Usage:', ' node vogen/java2js.js [java-array-text-path] [crypto-targets-json-path]', '', 'Defaults:', ' input : ./outall.txt', ' output: ./crypto-targets.json' ].join('\n')); } function readText(filePath) { return fs.readFileSync(filePath, 'utf8').replace(/^\uFEFF/, ''); } function parseJavaStringArrays(text) { const arrays = new Map(); const pattern = /(?:@\w+(?:\([^)]*\))?\s*)*(?:(?:private|protected|public)\s+)?String\s*\[\]\s+([A-Za-z_$][\w$]*)\s*=\s*\{([\s\S]*?)\}\s*;/g; let match; while ((match = pattern.exec(text)) !== null) { const [, name, body] = match; arrays.set(name, parseJavaStringValues(body)); } return arrays; } function parseJavaStringValues(body) { const values = []; const pattern = /"((?:\\.|[^"\\])*)"/g; let match; while ((match = pattern.exec(body)) !== null) { values.push(unescapeJavaString(match[1])); } return values; } function unescapeJavaString(value) { return value .replace(/\\n/g, '\n') .replace(/\\r/g, '\r') .replace(/\\t/g, '\t') .replace(/\\"/g, '"') .replace(/\\\\/g, '\\'); } function getArray(arrays, aliases, required) { for (const alias of aliases) { if (arrays.has(alias)) { return arrays.get(alias); } } if (required) { throw new Error(`Missing array variable. Expected one of: ${aliases.join(', ')}`); } return []; } function splitCsvValue(value) { if (typeof value !== 'string' || value.trim() === '') { return []; } return value.split(',').map((item) => item.trim()); } function requireAlignedLength(tableName, label, expectedLength, values, rowNo) { if (values.length !== expectedLength) { throw new Error( `${label} length mismatch at row #${rowNo} (${tableName}). Expected ${expectedLength}, got ${values.length}.` ); } } function buildTargetsFromArrays(tables, srcRows, destRows, typeRows, options) { const targets = []; tables.forEach((tableName, index) => { const rowNo = index + 1; const srcColumns = splitCsvValue(srcRows[index] || ''); const destColumns = splitCsvValue(destRows[index] || ''); const cryptoTypes = splitCsvValue(typeRows[index] || ''); requireAlignedLength(tableName, `${options.destLabel} columns`, srcColumns.length, destColumns, rowNo); requireAlignedLength(tableName, `${options.typeLabel} values`, srcColumns.length, cryptoTypes, rowNo); srcColumns.forEach((plainColumn, columnIndex) => { targets.push({ tableName, plainColumn, cryptoType: cryptoTypes[columnIndex], [options.destKey]: destColumns[columnIndex] }); }); }); return targets; } function mergeHashTargets(targets, hashTargets) { const usedTargetIndexes = new Set(); for (const hashTarget of hashTargets) { let targetIndex = -1; for (let index = targets.length - 1; index >= 0; index -= 1) { const target = targets[index]; if ( !usedTargetIndexes.has(index) && target.tableName === hashTarget.tableName && target.plainColumn === hashTarget.plainColumn && !target.hashColumn ) { targetIndex = index; break; } } if (targetIndex >= 0) { targets[targetIndex].hashColumn = hashTarget.hashColumn; usedTargetIndexes.add(targetIndex); continue; } targets.push({ tableName: hashTarget.tableName, plainColumn: hashTarget.plainColumn, cryptoType: hashTarget.cryptoType, hashColumn: hashTarget.hashColumn }); } } function normalizeTargets(targets) { return targets.map((target) => ({ tableName: target.tableName, plainColumn: target.plainColumn, cryptoType: target.cryptoType, encColumn: target.encColumn || '', hashColumn: target.hashColumn || '' })); } function convertJavaArraysToTargets(text) { const arrays = parseJavaStringArrays(text); const tables = getArray(arrays, ARRAY_ALIASES.table, true); const srcRows = getArray(arrays, ARRAY_ALIASES.src, true); const destRows = getArray(arrays, ARRAY_ALIASES.dest, true); const typeRows = getArray(arrays, ARRAY_ALIASES.type, true); const targets = buildTargetsFromArrays(tables, srcRows, destRows, typeRows, { destKey: 'encColumn', destLabel: 'destination', typeLabel: 'cryptoType' }); const hashTables = getArray(arrays, ARRAY_ALIASES.tableHash, false); const hashSrcRows = getArray(arrays, ARRAY_ALIASES.srcHash, false); const hashDestRows = getArray(arrays, ARRAY_ALIASES.destHash, false); const hashTypeRows = getArray(arrays, ARRAY_ALIASES.typeHash, false); if (hashTables.length > 0) { const hashTargets = buildTargetsFromArrays(hashTables, hashSrcRows, hashDestRows, hashTypeRows, { destKey: 'hashColumn', destLabel: 'hash destination', typeLabel: 'hash cryptoType' }); mergeHashTargets(targets, hashTargets); } return normalizeTargets(targets); } function main() { const args = process.argv.slice(2); if (args.includes('-h') || args.includes('--help')) { printUsage(); return; } const inputPath = path.resolve(process.cwd(), args[0] || 'outall.txt'); const outputPath = path.resolve(process.cwd(), args[1] || 'crypto-targets.json'); const targets = convertJavaArraysToTargets(readText(inputPath)); fs.writeFileSync(outputPath, `${JSON.stringify(targets, null, 2)}\n`, 'utf8'); console.log(`Generated ${outputPath}`); console.log(`Target count: ${targets.length}`); } try { main(); } catch (error) { console.error(error.message); process.exit(1); }

댓글

이 블로그의 인기 게시물

food eff privacy

판다 스픽 , 개인정보 처리방침 , Panda Speak Privacy Term

판다 수학 개인정보 처리방침 , Privacy , Panda Math