package com.perforce.common.asset; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.file.FileSystems; import java.nio.file.Path; import java.util.zip.GZIPOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.perforce.common.ConverterException; import com.perforce.common.Stats; import com.perforce.common.StatsType; import com.perforce.common.depot.DepotConvert; import com.perforce.common.depot.DepotInterface; import com.perforce.common.node.NodeAttributes; import com.perforce.common.node.PathMapTranslator; import com.perforce.config.CFG; import com.perforce.config.Config; import com.perforce.config.ConfigException; import com.perforce.cvs.process.TmpFileLogger; import com.perforce.svn.history.ChangeAction; import com.perforce.svn.parser.Content; public class AssetWriter { private Logger logger = LoggerFactory.getLogger(AssetWriter.class); private ChangeAction act; private String dir; private String path; private DepotInterface depot; private int blockSize = 8192; /** * Used to create Perforce archive files in Convert mode * * @param d * @param a * @throws ConfigException */ public AssetWriter(DepotConvert d, ChangeAction a) throws ConfigException { act = a; depot = d; path(act); } /** * Used to create local client side files in Import mode * * @param filePath */ public AssetWriter(String filePath) { path = filePath; File f = new File(filePath); dir = f.getParent(); } private void path(ChangeAction act) throws ConfigException { // generate path String nodePath = act.getPath(); dir = PathMapTranslator.getLbrPath(nodePath, depot) + ",d/"; path = dir + "1." + act.getEndChange(); // Convert to lower for C1 mode if ((Boolean) Config.get(CFG.P4_C1_MODE)) { dir = dir.toLowerCase(); path = path.toLowerCase(); } // Update stats Stats.inc(StatsType.archiveCount); // Main.updateNodeStats(); } public void check(ChangeAction act) throws Exception { // generate path String nodePath = act.getLazyCopy().getPath(); String dir = PathMapTranslator.getLbrPath(nodePath, depot) + ",d/"; String path = dir + "1." + act.getLazyCopy().getEndChange(); // Convert to lower for C1 mode if ((Boolean) Config.get(CFG.P4_C1_MODE)) { dir = dir.toLowerCase(); path = path.toLowerCase(); } // Check lazy reference for compressed archive if (act.getLazyCopy().isCompressed()) { path = path + ".gz"; } File file = new File(path); if (!file.exists()) { throw new ConverterException("Missing archive:\n\t" + act.getAction().toString() + " - " + path + ")"); } // Update stats Stats.inc(StatsType.branchActionCount); // Main.updateNodeStats(); } public String open() throws Exception { // create directory if needed. File d = new File(dir); if (d.mkdirs()) { // all OK, return. return path; } if (d.exists()) { // already exists, return. return path; } // try and fix the path logger.warn("Cannot create directory: " + d.getPath()); fixPath(d); if (d.mkdirs()) { // all OK, return. return path; } if (d.exists()) { // already exists, return. return path; } throw new ConverterException("Unable to fix path: " + d.getPath()); } private File fixPath(File path) { if (!path.isDirectory()) { logger.info("... cleaning: " + path); path.delete(); path = fixPath(path.getParentFile()); } return path; } public void write(Content content) throws Exception { AssetType type = content.getAssetType(); switch (type) { case P4_ASSET: // use cached file if present if (Config.isImportMode()) { writeClientFile(content); } else { writeArchive(content); } break; case PROPERTY: writeProperty(content); break; case TMP_FILE: writeCache(content); break; default: throw new Exception("Unknown AssetType: " + type); } } private void writeCache(Content content) throws Exception { String path = open(); if ((Boolean) Config.get(CFG.CVS_TMPLOG_ENABLED)) { TmpFileLogger.logTmpFile(path); } TranslateContent translate = new TranslateContent(content, path); // Links may need to be deleted before update to content. Path linkPath = FileSystems.getDefault().getPath(path); linkPath.toFile().delete(); translate.writeRAW(); } /** * Private internal method to format directory properties into a versioned * file and write to disk * * @param property */ private void writeProperty(Content content) throws Exception { NodeAttributes attributes = content.getAttributes(); FileOutputStream out = new FileOutputStream(open()); if (attributes != null) out.write(attributes.toString().getBytes()); out.flush(); out.close(); } /** * Internal method to write the conversion archive to disk using a seek * position and length offset in the Subversion dump file. * * @param content * @throws Exception */ private void writeClientFile(Content content) throws Exception { String path = open(); TranslateContent translate = new TranslateContent(content, path); // Links may need to be deleted before update to content. Path linkPath = FileSystems.getDefault().getPath(path); linkPath.toFile().delete(); translate.writeClient(); } /** * Internal method to write the conversion archive to disk using a seek * position and length offset in the Subversion dump file. * * @param content * @throws Exception */ private void writeArchive(Content content) throws Exception { String path = open(); TranslateContent translate = new TranslateContent(content, path); translate.writeArchive(); // compress archive file if +C used if (content.isCompressed()) { compressArchive(); } } /** * Compress archive file. Used if +C flag is set. * * @throws Exception */ private void compressArchive() throws Exception { if (logger.isDebugEnabled()) { logger.debug("Compressing archive: " + path); } FileOutputStream fout = new FileOutputStream(path + ".gz"); GZIPOutputStream gout = new GZIPOutputStream(fout); FileInputStream fin = new FileInputStream(path); byte[] buf = new byte[blockSize]; int len; while ((len = fin.read(buf)) > 0) { gout.write(buf, 0, len); } fin.close(); // flush and close gzip file gout.finish(); gout.close(); // unlink original archive File file = new File(path); file.delete(); } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 13876 | Paul Allen | Rename/move file(s) | ||
//guest/paul_allen/p4convert-maven/src/com/perforce/common/asset/AssetWriter.java | |||||
#1 | 13873 | Paul Allen | Branching using p4convert-maven | ||
//guest/perforce_software/p4convert/src/com/perforce/common/asset/AssetWriter.java | |||||
#6 | 12551 | Paul Allen |
Import mode workspace path fix code and logging. The issues only seems to occure when the configuration option com.p4convert.svn.mergeInfoEnabled is true. The merge seems to create a symlink or label then merge a directory over the top. |
||
#5 | 12521 | Paul Allen |
CVS: Audit logging when generating Tmp files from RCS. Creates a file "tmpFile.log" under the com.perforce.cvs.tmpDir and logging is enabled by default. com.perforce.cvs.audit.tmp=true |
||
#4 | 11071 | Paul Allen |
Path map translator for CVS and SVN paths. (undoc) To use create a path.map file with regex and group match. Only the first matching entry is used. The regex and group match are seperated by ', ' (or in regex terms ',\s+'). Lines starting with '#' are ignored. For example, 'trunk' is renamed to 'main', but other entries are left as-is. # path.map trunk/(.*), //import/main/{1} (.*), //import/{1} Note: if no file is found the default 'depot' and 'subPath' options are used to generate the map, preserving the original behaviour. CVS paths will always stat with the 'branch' name. 'main' for 1.1 and the symbol for other branches. # path.map main/projA/(.*), //import/projA/MAIN/{1} release_(.*)/projA/(.*), //import/projA/REL{1}/{2} (.*)/projA/(.*), //import/projA/TAG-{1}/{2} (.*), //import/unexpected/{1} Node: adding a catch all is a good idea. |
||
#3 | 11066 | Paul Allen |
Code refactor: Moved 'node' package from 'svn' to 'common'. |
||
#2 | 10916 | Paul Allen |
CVS Unicode Translation support. - tested for win1252 - fixes utf16 |
||
#1 | 9807 | Paul Allen | Initial import of p4-convert (from change 894340) |