/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Copyright (c) 2013, MPL CodeInside http://codeinside.ru */ package ru.codeinside.gws.api.impl; import org.codehaus.jackson.map.ObjectMapper; import ru.codeinside.gws.api.Packet; import ru.codeinside.gws.log.format.Metadata; import ru.codeinside.gws.log.format.Pack; import java.io.BufferedOutputStream; import java.io.Closeable; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; /** * Утилитные функции по работе с файлами. */ final public class Files { /** * Создать абсолютный путь к кеш-файлу внутри временного каталога. * Тривиальная схема именования prefix-id-file */ static File createCacheFileName(String path, String id, String fileName) { return new File(getAppTmpDir(path, id), fileName); } /** * Получить и кешировать в сессии временный каталог приложения. */ static File getAppTmpDir(String path, String suf) { File tmpDir = new File(path + File.separator + suf); tmpDir.mkdirs(); return tmpDir; } static void moveFromSpool(String marker) { Logger logger = LogServiceFileImpl.LOGGER; File source = Files.getAppTmpDir(LogSettings.getPath(true), marker); File target0 = Files.getAppTmpDir(LogSettings.getPath(false), marker.substring(marker.length() - 2, marker.length() - 1)); File target1 = new File(target0, marker.substring(marker.length() - 1)); if (!target1.exists() && !target1.mkdir()) { logger.log(Level.WARNING, "can't create " + target1); return; } File target = new File(target1, marker); if (target.exists()) { target.delete(); } if (!source.renameTo(target)) { logger.log(Level.INFO, "move from spool (override?)"); File[] files = source.listFiles(); if (files != null) { for (File file : files) { if (!file.renameTo(new File(target, file.getName()))) { logger.log(Level.INFO, "can't move " + file); } } } if (!source.delete()) { logger.log(Level.INFO, "can't delete " + source); } } } static void deleteFromSpool(String marker) { Logger logger = LogServiceFileImpl.LOGGER; File source = Files.getAppTmpDir(LogSettings.getPath(true), marker); File[] files = source.listFiles(); if (files != null) { for (File file : files) { if (!file.delete()) { logger.log(Level.INFO, "can't delete " + file); } } } if (!source.delete()) { logger.log(Level.INFO, "can't delete " + source); } } static File createSpoolFile(String name, String marker) { return createCacheFileName(LogSettings.getPath(true), marker, name); } static void writeMetadataToSpool(Metadata metadata, String marker) { OutputStream out = null; try { File spoolFile = Files.createSpoolFile(Metadata.METADATA, marker); ObjectMapper objectMapper = new ObjectMapper(); out = fileOut(spoolFile); objectMapper.writeValue(out, metadata); } catch (IOException e) { LogServiceFileImpl.LOGGER.log(Level.INFO, "metadata error", e); } finally { close(out); } } static OutputStream fileOut(File file) throws FileNotFoundException { return new BufferedOutputStream(new FileOutputStream(file), 16 * 1024); } static Pack getPack(Packet packet) { Pack pack = new Pack(); pack.caseNumber = packet.caseNumber; pack.date = packet.date; pack.exchangeType = packet.exchangeType; pack.oktmo = packet.oktmo; pack.originator = packet.originator == null ? null : packet.originator.code; pack.originRequestIdRef = packet.originRequestIdRef; pack.recipient = packet.recipient == null ? null : packet.recipient.code; pack.requestIdRef = packet.requestIdRef; pack.sender = packet.sender == null ? null : packet.sender.code; pack.serviceCode = packet.serviceCode; pack.serviceName = packet.serviceName; pack.status = String.valueOf(packet.status); pack.testMsg = packet.testMsg; pack.typeCode = String.valueOf(packet.typeCode); return pack; } static void close(Closeable... closeables) { for (Closeable closeable : closeables) { if (closeable != null) { try { closeable.close(); } catch (IOException e) { // skip } } } } static void logFailure(Metadata metadata, Throwable e, String fileName) { trimStackRecursive(e); StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); metadata.error = sw.toString(); writeMetadataToSpool(metadata, fileName); } static void trimStackRecursive(Throwable throwable) { while (throwable != null) { trimStack(throwable); throwable = throwable.getCause(); } } /** * Сократить стек до причины ошибки */ static void trimStack(Throwable throwable) { StackTraceElement[] stack = throwable.getStackTrace(); int length = 0; for (StackTraceElement e : stack) { length++; if (e.getClassName().startsWith("ru.codeinside.gws.core.")) { throwable.setStackTrace(Arrays.copyOf(stack, length)); break; } } } }