Example usage for java.io StringWriter StringWriter

List of usage examples for java.io StringWriter StringWriter

Introduction

In this page you can find the example usage for java.io StringWriter StringWriter.

Prototype

public StringWriter() 

Source Link

Document

Create a new string writer using the default initial string-buffer size.

Usage

From source file:org.apache.flink.benchmark.Runner.java

public static void main(String[] args) throws Exception {
    final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
    env.getConfig().enableObjectReuse();
    env.getConfig().disableSysoutLogging();

    ParameterTool parameters = ParameterTool.fromArgs(args);

    if (!(parameters.has("p") && parameters.has("types") && parameters.has("algorithms"))) {
        printUsage();//from www .ja v  a2s. co m
        System.exit(-1);
    }

    int parallelism = parameters.getInt("p");
    env.setParallelism(parallelism);

    Set<IdType> types = new HashSet<>();

    if (parameters.get("types").equals("all")) {
        types.add(IdType.INT);
        types.add(IdType.LONG);
        types.add(IdType.STRING);
    } else {
        for (String type : parameters.get("types").split(",")) {
            if (type.toLowerCase().equals("int")) {
                types.add(IdType.INT);
            } else if (type.toLowerCase().equals("long")) {
                types.add(IdType.LONG);
            } else if (type.toLowerCase().equals("string")) {
                types.add(IdType.STRING);
            } else {
                printUsage();
                throw new RuntimeException("Unknown type: " + type);
            }
        }
    }

    Queue<RunnerWithScore> queue = new PriorityQueue<>();

    if (parameters.get("algorithms").equals("all")) {
        for (Map.Entry<String, Class> entry : AVAILABLE_ALGORITHMS.entrySet()) {
            for (IdType type : types) {
                AlgorithmRunner runner = (AlgorithmRunner) entry.getValue().newInstance();
                runner.initialize(type, SAMPLES, parallelism);
                runner.warmup(env);
                queue.add(new RunnerWithScore(runner, 1.0));
            }
        }
    } else {
        for (String algorithm : parameters.get("algorithms").split(",")) {
            double ratio = 1.0;
            if (algorithm.contains("=")) {
                String[] split = algorithm.split("=");
                algorithm = split[0];
                ratio = Double.parseDouble(split[1]);
            }

            if (AVAILABLE_ALGORITHMS.containsKey(algorithm.toLowerCase())) {
                Class clazz = AVAILABLE_ALGORITHMS.get(algorithm.toLowerCase());

                for (IdType type : types) {
                    AlgorithmRunner runner = (AlgorithmRunner) clazz.newInstance();
                    runner.initialize(type, SAMPLES, parallelism);
                    runner.warmup(env);
                    queue.add(new RunnerWithScore(runner, ratio));
                }
            } else {
                printUsage();
                throw new RuntimeException("Unknown algorithm: " + algorithm);
            }
        }
    }

    JsonFactory factory = new JsonFactory();

    while (queue.size() > 0) {
        RunnerWithScore current = queue.poll();
        AlgorithmRunner runner = current.getRunner();

        StringWriter writer = new StringWriter();
        JsonGenerator gen = factory.createGenerator(writer);
        gen.writeStartObject();
        gen.writeStringField("algorithm", runner.getClass().getSimpleName());

        boolean running = true;

        while (running) {
            try {
                runner.run(env, gen);
                running = false;
            } catch (ProgramInvocationException e) {
                // only suppress job cancellations
                if (!(e.getCause() instanceof JobCancellationException)) {
                    throw e;
                }
            }
        }

        JobExecutionResult result = env.getLastJobExecutionResult();

        long runtime_ms = result.getNetRuntime();
        gen.writeNumberField("runtime_ms", runtime_ms);
        current.credit(runtime_ms);

        if (!runner.finished()) {
            queue.add(current);
        }

        gen.writeObjectFieldStart("accumulators");
        for (Map.Entry<String, Object> accumulatorResult : result.getAllAccumulatorResults().entrySet()) {
            gen.writeStringField(accumulatorResult.getKey(), accumulatorResult.getValue().toString());
        }
        gen.writeEndObject();

        gen.writeEndObject();
        gen.close();
        System.out.println(writer.toString());
    }
}

From source file:gobblin.runtime.util.JobStateToJsonConverter.java

@SuppressWarnings("all")
public static void main(String[] args) throws Exception {
    Option sysConfigOption = Option.builder("sc").argName("system configuration file")
            .desc("Gobblin system configuration file").longOpt("sysconfig").hasArgs().build();
    Option storeUrlOption = Option.builder("u").argName("gobblin state store URL")
            .desc("Gobblin state store root path URL").longOpt("storeurl").hasArgs().required().build();
    Option jobNameOption = Option.builder("n").argName("gobblin job name").desc("Gobblin job name")
            .longOpt("name").hasArgs().required().build();
    Option jobIdOption = Option.builder("i").argName("gobblin job id").desc("Gobblin job id").longOpt("id")
            .hasArgs().build();/*from   www  .jav a  2  s.  c  o  m*/
    Option convertAllOption = Option.builder("a")
            .desc("Whether to convert all past job states of the given job").longOpt("all").build();
    Option keepConfigOption = Option.builder("kc").desc("Whether to keep all configuration properties")
            .longOpt("keepConfig").build();
    Option outputToFile = Option.builder("t").argName("output file name").desc("Output file name")
            .longOpt("toFile").hasArgs().build();

    Options options = new Options();
    options.addOption(sysConfigOption);
    options.addOption(storeUrlOption);
    options.addOption(jobNameOption);
    options.addOption(jobIdOption);
    options.addOption(convertAllOption);
    options.addOption(keepConfigOption);
    options.addOption(outputToFile);

    CommandLine cmd = null;
    try {
        CommandLineParser parser = new DefaultParser();
        cmd = parser.parse(options, args);
    } catch (ParseException pe) {
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp("JobStateToJsonConverter", options);
        System.exit(1);
    }

    Properties sysConfig = new Properties();
    if (cmd.hasOption(sysConfigOption.getLongOpt())) {
        sysConfig = JobConfigurationUtils.fileToProperties(cmd.getOptionValue(sysConfigOption.getLongOpt()));
    }

    JobStateToJsonConverter converter = new JobStateToJsonConverter(sysConfig, cmd.getOptionValue('u'),
            cmd.hasOption("kc"));
    StringWriter stringWriter = new StringWriter();
    if (cmd.hasOption('i')) {
        converter.convert(cmd.getOptionValue('n'), cmd.getOptionValue('i'), stringWriter);
    } else {
        if (cmd.hasOption('a')) {
            converter.convertAll(cmd.getOptionValue('n'), stringWriter);
        } else {
            converter.convert(cmd.getOptionValue('n'), stringWriter);
        }
    }

    if (cmd.hasOption('t')) {
        Closer closer = Closer.create();
        try {
            FileOutputStream fileOutputStream = closer.register(new FileOutputStream(cmd.getOptionValue('t')));
            OutputStreamWriter outputStreamWriter = closer.register(
                    new OutputStreamWriter(fileOutputStream, ConfigurationKeys.DEFAULT_CHARSET_ENCODING));
            BufferedWriter bufferedWriter = closer.register(new BufferedWriter(outputStreamWriter));
            bufferedWriter.write(stringWriter.toString());
        } catch (Throwable t) {
            throw closer.rethrow(t);
        } finally {
            closer.close();
        }
    } else {
        System.out.println(stringWriter.toString());
    }
}

From source file:com.sludev.mssqlapplylog.MSSQLApplyLogMain.java

public static void main(String[] args) {
    CommandLineParser parser = new DefaultParser();
    Options options = new Options();

    // Most of the following defaults should be changed in
    // the --conf or "conf.properties" file
    String sqlURL = null;//from   w ww.  j ava2  s.  c  o  m
    String sqlUser = null;
    String sqlPass = null;
    String sqlDb = null;
    String sqlHost = "127.0.0.1";
    String backupDirStr = null;
    String laterThanStr = "";
    String fullBackupPathStr = null;
    String fullBackupPatternStr = "(?:[\\w_-]+?)(\\d+)\\.bak";
    String fullBackupDatePatternStr = "yyyyMMddHHmm";
    String sqlProcessUser = null;
    String logBackupPatternStr = "(.*)\\.trn";
    String logBackupDatePatternStr = "yyyyMMddHHmmss";

    boolean doFullRestore = false;
    Boolean useLogFileLastMode = null;
    Boolean monitorLogBackupDir = null;

    options.addOption(Option.builder().longOpt("conf").desc("Configuration file.").hasArg().build());

    options.addOption(Option.builder().longOpt("laterthan").desc("'Later Than' file filter.").hasArg().build());

    options.addOption(Option.builder().longOpt("restore-full")
            .desc("Restore the full backup before continuing.").build());

    options.addOption(Option.builder().longOpt("use-lastmod")
            .desc("Sort/filter the log backups using their File-System 'Last Modified' date.").build());

    options.addOption(Option.builder().longOpt("monitor-backup-dir")
            .desc("Monitor the backup directory for new log backups, and apply them.").build());

    CommandLine line = null;
    try {
        try {
            line = parser.parse(options, args);
        } catch (ParseException ex) {
            throw new MSSQLApplyLogException(String.format("Error parsing command line.'%s'", ex.getMessage()),
                    ex);
        }

        String confFile = null;

        // Process the command line arguments
        Iterator cmdI = line.iterator();
        while (cmdI.hasNext()) {
            Option currOpt = (Option) cmdI.next();
            String currOptName = currOpt.getLongOpt();

            switch (currOptName) {
            case "conf":
                // Parse the configuration file
                confFile = currOpt.getValue();
                break;

            case "laterthan":
                // "Later Than" file date filter
                laterThanStr = currOpt.getValue();
                break;

            case "restore-full":
                // Do a full backup restore before restoring logs
                doFullRestore = true;
                break;

            case "monitor-backup-dir":
                // Monitor the backup directory for new logs
                monitorLogBackupDir = true;
                break;

            case "use-lastmod":
                // Use the last-modified date on Log Backup files for sorting/filtering
                useLogFileLastMode = true;
                break;
            }
        }

        Properties confProperties = null;

        if (StringUtils.isBlank(confFile) || Files.isReadable(Paths.get(confFile)) == false) {
            throw new MSSQLApplyLogException(
                    "Missing or unreadable configuration file.  Please specify --conf");
        } else {
            // Process the conf.properties file
            confProperties = new Properties();
            try {
                confProperties.load(Files.newBufferedReader(Paths.get(confFile)));
            } catch (IOException ex) {
                throw new MSSQLApplyLogException("Error loading properties file", ex);
            }

            sqlURL = confProperties.getProperty("sqlURL", "");
            sqlUser = confProperties.getProperty("sqlUser", "");
            sqlPass = confProperties.getProperty("sqlPass", "");
            sqlDb = confProperties.getProperty("sqlDb", "");
            sqlHost = confProperties.getProperty("sqlHost", "");
            backupDirStr = confProperties.getProperty("backupDir", "");

            if (StringUtils.isBlank(laterThanStr)) {
                laterThanStr = confProperties.getProperty("laterThan", "");
            }

            fullBackupPathStr = confProperties.getProperty("fullBackupPath", fullBackupPathStr);
            fullBackupPatternStr = confProperties.getProperty("fullBackupPattern", fullBackupPatternStr);
            fullBackupDatePatternStr = confProperties.getProperty("fullBackupDatePattern",
                    fullBackupDatePatternStr);
            sqlProcessUser = confProperties.getProperty("sqlProcessUser", "");

            logBackupPatternStr = confProperties.getProperty("logBackupPattern", logBackupPatternStr);
            logBackupDatePatternStr = confProperties.getProperty("logBackupDatePattern",
                    logBackupDatePatternStr);

            if (useLogFileLastMode == null) {
                String useLogFileLastModeStr = confProperties.getProperty("useLogFileLastMode", "false");
                useLogFileLastMode = Boolean
                        .valueOf(StringUtils.lowerCase(StringUtils.trim(useLogFileLastModeStr)));
            }

            if (monitorLogBackupDir == null) {
                String monitorBackupDirStr = confProperties.getProperty("monitorBackupDir", "false");
                monitorLogBackupDir = Boolean
                        .valueOf(StringUtils.lowerCase(StringUtils.trim(monitorBackupDirStr)));
            }
        }
    } catch (MSSQLApplyLogException ex) {
        try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) {
            pw.append(String.format("Error : '%s'\n\n", ex.getMessage()));

            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp(pw, 80, "\njava -jar mssqlapplylog.jar ",
                    "\nThe MSSQLApplyLog application can be used in a variety of options and modes.\n", options,
                    0, 2, " All Rights Reserved.", true);

            System.out.println(sw.toString());
        } catch (IOException iex) {
            LOGGER.debug("Error processing usage", iex);
        }

        System.exit(1);
    }

    MSSQLApplyLogConfig config = MSSQLApplyLogConfig.from(backupDirStr, fullBackupPathStr,
            fullBackupDatePatternStr, laterThanStr, fullBackupPatternStr, logBackupPatternStr,
            logBackupDatePatternStr, sqlHost, sqlDb, sqlUser, sqlPass, sqlURL, sqlProcessUser,
            useLogFileLastMode, doFullRestore, monitorLogBackupDir);

    MSSQLApplyLog logProc = MSSQLApplyLog.from(config);

    BasicThreadFactory thFactory = new BasicThreadFactory.Builder().namingPattern("restoreThread-%d").build();

    ExecutorService mainThreadExe = Executors.newSingleThreadExecutor(thFactory);

    Future<Integer> currRunTask = mainThreadExe.submit(logProc);

    mainThreadExe.shutdown();

    Integer resp = 0;
    try {
        resp = currRunTask.get();
    } catch (InterruptedException ex) {
        LOGGER.error("Application 'main' thread was interrupted", ex);
    } catch (ExecutionException ex) {
        LOGGER.error("Application 'main' thread execution error", ex);
    } finally {
        // If main leaves for any reason, shutdown all threads
        mainThreadExe.shutdownNow();
    }

    System.exit(resp);
}

From source file:dk.defxws.fedoragsearch.server.GTransformer.java

public static void main(String[] args) {
    int argCount = 2;
    try {//from  ww w .  j av  a2s.c o m
        if (args.length == argCount) {
            File f = new File(args[1]);
            StreamSource ss = new StreamSource(new File(args[1]));
            GTransformer gt = new GTransformer();
            StreamResult destStream = new StreamResult(new StringWriter());
            gt.transform(args[0], ss, destStream);
            StringWriter sw = (StringWriter) destStream.getWriter();
            System.out.print(sw.getBuffer().toString());
        } else {
            throw new IOException("Must supply " + argCount + " arguments.");
        }
    } catch (Exception e) {
        e.printStackTrace();
        System.err.println("Usage: GTransformer xsltName xmlFileName");
    }
}

From source file:com.appeligo.responsetest.ServerResponseChecker.java

/**
 * @param args/*ww w .  j a  va2 s  .c om*/
 */
public static void main(String[] args) {

    PatternLayout pattern = new PatternLayout("%d{ISO8601} %-5p [%-c{1} - %t] - %m%n");
    ConsoleAppender consoleAppender = new ConsoleAppender(pattern);
    LevelRangeFilter infoFilter = new LevelRangeFilter();
    infoFilter.setLevelMin(Level.INFO);
    consoleAppender.addFilter(infoFilter);
    BasicConfigurator.configure(consoleAppender);

    String configFile = "/etc/flip.tv/responsetest.xml";

    if (args.length > 0) {
        if (args.length == 2 && args[0].equals("-config")) {
            configFile = args[1];
        } else {
            log.error("Usage: java " + ServerResponseChecker.class.getName() + " [-config <xmlfile>]");
            System.exit(1);
        }
    }

    try {
        XMLConfiguration config = new XMLConfiguration(configFile);

        logFile = config.getString("logFile", logFile);
        servlet = config.getString("servlet", servlet);
        timeoutSeconds = config.getLong("timeoutSeconds", timeoutSeconds);
        responseTimeThresholdSeconds = config.getLong("responseTimeThresholdSeconds",
                responseTimeThresholdSeconds);
        reporter = config.getString("reporter", reporter);
        smtpServer = config.getString("smtpServer", smtpServer);
        smtpUsername = config.getString("smtpUsername", smtpUsername);
        smtpPassword = config.getString("smtpPassword", smtpPassword);
        smtpDebug = config.getBoolean("smtpDebug", smtpDebug);
        mailTo = config.getString("mailTo", mailTo);
    } catch (ConfigurationException e) {
        e.printStackTrace();
    }

    marker = logFile + ".mailed";

    try {
        BasicConfigurator.configure(new RollingFileAppender(pattern, logFile, true));
    } catch (IOException e1) {
        e1.printStackTrace();
    }

    // Add email appender
    SMTPAppender mailme = new SMTPAppender();
    LevelRangeFilter warnFilter = new LevelRangeFilter();
    warnFilter.setLevelMin(Level.WARN);
    mailme.addFilter(warnFilter);
    mailme.setSMTPDebug(smtpDebug);
    mailme.setSMTPHost(smtpServer);
    mailme.setTo(mailTo);
    mailme.setFrom(reporter + " <" + smtpUsername + ">");
    mailme.setBufferSize(1);
    mailme.setSubject(servlet + " Not Responding!");
    mailme.setSMTPUsername(smtpUsername);
    mailme.setSMTPPassword(smtpPassword);
    mailme.setLayout(new SimpleLayout());
    mailme.activateOptions();
    mailme.setLayout(pattern);
    BasicConfigurator.configure(mailme);

    long before;
    ConnectionThread connectionThread = new ConnectionThread();
    connectionThread.start();
    synchronized (connectionThread) {
        connectionThread.setOkToGo(true);
        connectionThread.notifyAll();
        before = System.currentTimeMillis();
        long delay = timeoutSeconds * 1000;
        while (!done && delay > 0) {
            try {
                connectionThread.wait(delay);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            delay -= (System.currentTimeMillis() - before);
        }
    }
    long after = System.currentTimeMillis();
    responseMillis = after - before;
    String reportStatus = "Could not report";
    try {
        StringBuilder sb = new StringBuilder();
        sb.append(servlet + "/responsetest/report.action");
        sb.append("?reporter=" + URLEncoder.encode(reporter));
        sb.append("&status=" + URLEncoder.encode(status));
        sb.append("&bytesRead=" + bytesRead);
        sb.append("&timedOut=" + (!done));
        if (throwable == null) {
            sb.append("&exception=none");
        } else {
            sb.append("&exception="
                    + URLEncoder.encode(throwable.getClass().getName() + "-" + throwable.getMessage()));
        }
        sb.append("&responseMillis=" + responseMillis);
        URL reportURL = new URL(sb.toString());
        connection = (HttpURLConnection) reportURL.openConnection();
        connection.connect();
        reportStatus = connection.getResponseCode() + " - " + connection.getResponseMessage();
    } catch (Throwable t) {
        reportStatus = t.getClass().getName() + "-" + t.getMessage();
    }
    StringBuilder sb = new StringBuilder();
    sb.append(servlet + ": ");
    sb.append(status + ", " + bytesRead + " bytes, ");
    if (done) {
        sb.append("DONE, ");
    } else {
        sb.append("TIMED OUT, ");
    }
    sb.append(responseMillis + " millisecond response, ");
    sb.append(" report status=" + reportStatus);
    File markerFile = new File(marker);
    if (done && status.startsWith("200") && (throwable == null)) {
        if ((responseMillis / 1000) < responseTimeThresholdSeconds) {
            if (markerFile.exists()) {
                markerFile.delete();
            }
            log.debug(sb.toString());
        } else {
            if (markerFile.exists()) {
                log.info(sb.toString());
            } else {
                try {
                    new FileOutputStream(marker).close();
                    log.warn(sb.toString());
                } catch (IOException e) {
                    log.info(sb.toString());
                    log.info("Can't send email alert because could not write marker file: " + marker + ". "
                            + e.getMessage());
                }
            }
        }
    } else {
        if (throwable != null) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            throwable.printStackTrace(pw);
            sb.append(sw.toString());
        }
        if (markerFile.exists()) {
            log.info(sb.toString());
        } else {
            try {
                new FileOutputStream(marker).close();
                log.fatal(sb.toString()); // chosen appender layout ignoresThrowable()
            } catch (IOException e) {
                log.info(sb.toString());
                log.info("Can't send email alert because could not write marker file: " + marker + ". "
                        + e.getMessage());
            }
        }
    }
}

From source file:ekb.elastic.ingest.TaxiQuery.java

public static void main(String... args) {

    Options options = new Options();
    HelpFormatter help = new HelpFormatter();

    try {/*w  w  w.j  av a 2  s . co  m*/
        Option hostOpt = new Option("h", "host", true, "ElasticSearch URL");
        hostOpt.setArgs(1);
        hostOpt.setRequired(true);
        Option portOpt = new Option("p", "port", true, "ElasticSearch URL");
        portOpt.setArgs(1);
        portOpt.setRequired(true);
        Option clusterOpt = new Option("c", "cluster", true, "Cluster");
        clusterOpt.setArgs(1);
        clusterOpt.setRequired(true);
        Option indexOpt = new Option("i", "index", true, "The index");
        indexOpt.setArgs(1);
        indexOpt.setRequired(true);

        Option pickupTimeOpt = new Option("u", "pickup", true, "The pickup time");
        pickupTimeOpt.setArgs(1);
        pickupTimeOpt.setRequired(true);
        Option dropTimeOpt = new Option("d", "dropoff", true, "The dropoff time");
        dropTimeOpt.setArgs(1);
        dropTimeOpt.setRequired(true);

        options.addOption(hostOpt);
        options.addOption(portOpt);
        options.addOption(clusterOpt);
        options.addOption(indexOpt);
        options.addOption(pickupTimeOpt);
        options.addOption(dropTimeOpt);

        GnuParser parser = new GnuParser();
        CommandLine cmd = parser.parse(options, args);

        Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", cmd.getOptionValue('c'))
                .build();
        Client client = new TransportClient(settings).addTransportAddress(new InetSocketTransportAddress(
                cmd.getOptionValue('h'), Integer.parseInt(cmd.getOptionValue('p'))));

        TaxiQuery tq = new TaxiQuery();

        TaxiStats stats = tq.getTaxiStats(client, cmd.getOptionValues("i"));

        log.info("Results:\n" + stats.toDateString());

        sdf.parse(cmd.getOptionValue("u"));
        sdf.parse(cmd.getOptionValue("d"));

        // 2013-01-01T10:10:00

        ArrayList<TaxiBucket> list = tq.getInterval(client, cmd.getOptionValues("index"),
                cmd.getOptionValue("u"), cmd.getOptionValue("d"), 60);

        log.info("List size is: " + list.size());

        client.close();

    } catch (ParseException pe) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);

        help.printUsage(pw, 80, TaxiQuery.class.getName(), options);

        log.error(sw.toString());

    } catch (TaxiQueryException e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        log.error(sw.toString());
    } catch (java.text.ParseException e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        log.error(sw.toString());
    }
}

From source file:Main.java

public static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    t.printStackTrace(pw);//w ww  . j av a 2s.c  o  m
    return sw.toString();
}

From source file:Main.java

public static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw, true);
    t.printStackTrace(pw);/*from ww w  .  java 2  s  .co m*/
    pw.flush();
    sw.flush();
    return sw.toString();
}

From source file:Main.java

public static String getExceptionStackTrace(Exception e) {
    StringWriter sw = new StringWriter();
    e.printStackTrace(new PrintWriter(sw));
    return sw.toString();
}

From source file:Main.java

public static String getExceptionStackTrace(Exception e) {
    Writer writer = new StringWriter();
    PrintWriter printWriter = new PrintWriter(writer);
    e.printStackTrace(printWriter);//from  w  w w . ja v  a  2s  .  c  o m
    return writer.toString();
}