Source Code Cross Referenced for SVNAdminArea14.java in  » Source-Control » tmatesoft-SVN » org » tmatesoft » svn » core » internal » wc » admin » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Source Control » tmatesoft SVN » org.tmatesoft.svn.core.internal.wc.admin 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * ====================================================================
0003:         * Copyright (c) 2004-2008 TMate Software Ltd.  All rights reserved.
0004:         *
0005:         * This software is licensed as described in the file COPYING, which
0006:         * you should have received as part of this distribution.  The terms
0007:         * are also available at http://svnkit.com/license.html
0008:         * If newer versions of this license are posted there, you may use a
0009:         * newer version instead, at your option.
0010:         * ====================================================================
0011:         */
0012:        package org.tmatesoft.svn.core.internal.wc.admin;
0013:
0014:        import java.io.BufferedOutputStream;
0015:        import java.io.BufferedReader;
0016:        import java.io.File;
0017:        import java.io.FileOutputStream;
0018:        import java.io.IOException;
0019:        import java.io.InputStreamReader;
0020:        import java.io.OutputStream;
0021:        import java.io.OutputStreamWriter;
0022:        import java.io.Writer;
0023:        import java.util.ArrayList;
0024:        import java.util.Collections;
0025:        import java.util.Date;
0026:        import java.util.HashMap;
0027:        import java.util.HashSet;
0028:        import java.util.Iterator;
0029:        import java.util.LinkedList;
0030:        import java.util.List;
0031:        import java.util.Map;
0032:        import java.util.Set;
0033:
0034:        import org.tmatesoft.svn.core.SVNErrorCode;
0035:        import org.tmatesoft.svn.core.SVNErrorMessage;
0036:        import org.tmatesoft.svn.core.SVNException;
0037:        import org.tmatesoft.svn.core.SVNNodeKind;
0038:        import org.tmatesoft.svn.core.SVNProperty;
0039:        import org.tmatesoft.svn.core.internal.io.fs.FSFile;
0040:        import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
0041:        import org.tmatesoft.svn.core.internal.util.SVNFormatUtil;
0042:        import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
0043:        import org.tmatesoft.svn.core.internal.util.SVNTimeUtil;
0044:        import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
0045:        import org.tmatesoft.svn.core.internal.wc.SVNFileListUtil;
0046:        import org.tmatesoft.svn.core.internal.wc.SVNFileType;
0047:        import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
0048:        import org.tmatesoft.svn.core.internal.wc.SVNProperties;
0049:        import org.tmatesoft.svn.util.SVNDebugLog;
0050:
0051:        /**
0052:         * @version 1.1.1
0053:         * @author  TMate Software Ltd.
0054:         */
0055:        public class SVNAdminArea14 extends SVNAdminArea {
0056:            public static final String[] ourCachableProperties = new String[] {
0057:                    SVNProperty.SPECIAL, SVNProperty.EXTERNALS,
0058:                    SVNProperty.NEEDS_LOCK };
0059:
0060:            public static final int WC_FORMAT = 8;
0061:
0062:            private static final String ATTRIBUTE_COPIED = "copied";
0063:            private static final String ATTRIBUTE_DELETED = "deleted";
0064:            private static final String ATTRIBUTE_ABSENT = "absent";
0065:            private static final String ATTRIBUTE_INCOMPLETE = "incomplete";
0066:            private static final String THIS_DIR = "";
0067:
0068:            private File myLockFile;
0069:            private File myEntriesFile;
0070:
0071:            private static boolean ourIsOptimizedWritingEnabled;
0072:
0073:            public SVNAdminArea14(File dir) {
0074:                super (dir);
0075:                myLockFile = new File(getAdminDirectory(), "lock");
0076:                myEntriesFile = new File(getAdminDirectory(), "entries");
0077:            }
0078:
0079:            public static void setOptimizedWritingEnabled(boolean enabled) {
0080:                ourIsOptimizedWritingEnabled = enabled;
0081:            }
0082:
0083:            public static String[] getCachableProperties() {
0084:                return ourCachableProperties;
0085:            }
0086:
0087:            public void saveWCProperties(boolean close) throws SVNException {
0088:                Map wcPropsCache = getWCPropertiesStorage(false);
0089:                if (wcPropsCache == null) {
0090:                    return;
0091:                }
0092:
0093:                boolean hasAnyProps = false;
0094:                File dstFile = getAdminFile("all-wcprops");
0095:                File tmpFile = getAdminFile("tmp/all-wcprops");
0096:
0097:                for (Iterator entries = wcPropsCache.keySet().iterator(); entries
0098:                        .hasNext();) {
0099:                    String name = (String) entries.next();
0100:                    SVNVersionedProperties props = (SVNVersionedProperties) wcPropsCache
0101:                            .get(name);
0102:                    if (!props.isEmpty()) {
0103:                        hasAnyProps = true;
0104:                        break;
0105:                    }
0106:                }
0107:
0108:                if (hasAnyProps) {
0109:                    OutputStream target = null;
0110:                    try {
0111:                        target = SVNFileUtil.openFileForWriting(tmpFile);
0112:                        SVNVersionedProperties props = (SVNVersionedProperties) wcPropsCache
0113:                                .get(getThisDirName());
0114:                        if (props != null && !props.isEmpty()) {
0115:                            SVNProperties.setProperties(props.asMap(), target,
0116:                                    SVNProperties.SVN_HASH_TERMINATOR);
0117:                        } else {
0118:                            SVNProperties.setProperties(Collections.EMPTY_MAP,
0119:                                    target, SVNProperties.SVN_HASH_TERMINATOR);
0120:                        }
0121:
0122:                        for (Iterator entries = wcPropsCache.keySet()
0123:                                .iterator(); entries.hasNext();) {
0124:                            String name = (String) entries.next();
0125:                            if (getThisDirName().equals(name)) {
0126:                                continue;
0127:                            }
0128:                            props = (SVNVersionedProperties) wcPropsCache
0129:                                    .get(name);
0130:                            if (!props.isEmpty()) {
0131:                                target.write(name.getBytes("UTF-8"));
0132:                                target.write('\n');
0133:                                SVNProperties.setProperties(props.asMap(),
0134:                                        target,
0135:                                        SVNProperties.SVN_HASH_TERMINATOR);
0136:                            }
0137:                        }
0138:                    } catch (IOException ioe) {
0139:                        SVNErrorMessage err = SVNErrorMessage.create(
0140:                                SVNErrorCode.IO_ERROR, ioe
0141:                                        .getLocalizedMessage());
0142:                        SVNErrorManager.error(err, ioe);
0143:                    } finally {
0144:                        SVNFileUtil.closeFile(target);
0145:                    }
0146:                    SVNFileUtil.rename(tmpFile, dstFile);
0147:                    SVNFileUtil.setReadonly(dstFile, true);
0148:                } else {
0149:                    SVNFileUtil.deleteFile(dstFile);
0150:                }
0151:                if (close) {
0152:                    closeWCProperties();
0153:                }
0154:            }
0155:
0156:            public SVNVersionedProperties getBaseProperties(String name)
0157:                    throws SVNException {
0158:                Map basePropsCache = getBasePropertiesStorage(true);
0159:                SVNVersionedProperties props = (SVNVersionedProperties) basePropsCache
0160:                        .get(name);
0161:                if (props != null) {
0162:                    return props;
0163:                }
0164:
0165:                Map baseProps = null;
0166:                try {
0167:                    baseProps = readBaseProperties(name);
0168:                } catch (SVNException svne) {
0169:                    SVNErrorMessage err = svne.getErrorMessage().wrap(
0170:                            "Failed to load properties from disk");
0171:                    SVNErrorManager.error(err);
0172:                }
0173:
0174:                props = new SVNProperties13(baseProps);
0175:                basePropsCache.put(name, props);
0176:                return props;
0177:            }
0178:
0179:            public SVNVersionedProperties getRevertProperties(String name)
0180:                    throws SVNException {
0181:                Map revertPropsCache = getRevertPropertiesStorage(true);
0182:                SVNVersionedProperties props = (SVNVersionedProperties) revertPropsCache
0183:                        .get(name);
0184:                if (props != null) {
0185:                    return props;
0186:                }
0187:
0188:                Map revertProps = null;
0189:                try {
0190:                    revertProps = readRevertProperties(name);
0191:                } catch (SVNException svne) {
0192:                    SVNErrorMessage err = svne.getErrorMessage().wrap(
0193:                            "Failed to load properties from disk");
0194:                    SVNErrorManager.error(err);
0195:                }
0196:
0197:                props = new SVNProperties13(revertProps);
0198:                revertPropsCache.put(name, props);
0199:                return props;
0200:            }
0201:
0202:            public SVNVersionedProperties getProperties(String name)
0203:                    throws SVNException {
0204:                Map propsCache = getPropertiesStorage(true);
0205:                SVNVersionedProperties props = (SVNVersionedProperties) propsCache
0206:                        .get(name);
0207:                if (props != null) {
0208:                    return props;
0209:                }
0210:
0211:                final String entryName = name;
0212:                props = new SVNProperties14(null, this , name) {
0213:
0214:                    protected Map loadProperties() throws SVNException {
0215:                        Map props = getPropertiesMap();
0216:                        if (props == null) {
0217:                            try {
0218:                                props = readProperties(entryName);
0219:                            } catch (SVNException svne) {
0220:                                SVNErrorMessage err = svne
0221:                                        .getErrorMessage()
0222:                                        .wrap(
0223:                                                "Failed to load properties from disk");
0224:                                SVNErrorManager.error(err);
0225:                            }
0226:                            props = props != null ? props : new HashMap();
0227:                            setPropertiesMap(props);
0228:                        }
0229:                        return props;
0230:                    }
0231:                };
0232:
0233:                propsCache.put(name, props);
0234:                return props;
0235:            }
0236:
0237:            public SVNVersionedProperties getWCProperties(String entryName)
0238:                    throws SVNException {
0239:                SVNEntry entry = getEntry(entryName, false);
0240:                if (entry == null) {
0241:                    return null;
0242:                }
0243:
0244:                Map wcPropsCache = getWCPropertiesStorage(true);
0245:                SVNVersionedProperties props = (SVNVersionedProperties) wcPropsCache
0246:                        .get(entryName);
0247:                if (props != null) {
0248:                    return props;
0249:                }
0250:
0251:                if (wcPropsCache.isEmpty()) {
0252:                    wcPropsCache = readAllWCProperties();
0253:                }
0254:
0255:                props = (SVNVersionedProperties) wcPropsCache.get(entryName);
0256:                if (props == null) {
0257:                    props = new SVNProperties13(new HashMap());
0258:                    wcPropsCache.put(entryName, props);
0259:                }
0260:                return props;
0261:            }
0262:
0263:            private Map readAllWCProperties() throws SVNException {
0264:                Map wcPropsCache = getWCPropertiesStorage(true);
0265:                wcPropsCache.clear();
0266:                File propertiesFile = getAdminFile("all-wcprops");
0267:                if (!propertiesFile.exists()) {
0268:                    return wcPropsCache;
0269:                }
0270:
0271:                FSFile wcpropsFile = null;
0272:                try {
0273:                    wcpropsFile = new FSFile(propertiesFile);
0274:                    Map wcProps = wcpropsFile.readProperties(false);
0275:                    SVNVersionedProperties entryWCProps = new SVNProperties13(
0276:                            wcProps);
0277:                    wcPropsCache.put(getThisDirName(), entryWCProps);
0278:
0279:                    String name = null;
0280:                    StringBuffer buffer = new StringBuffer();
0281:                    while (true) {
0282:                        try {
0283:                            name = wcpropsFile.readLine(buffer);
0284:                        } catch (SVNException e) {
0285:                            if (e.getErrorMessage().getErrorCode() == SVNErrorCode.STREAM_UNEXPECTED_EOF
0286:                                    && buffer.length() > 0) {
0287:                                SVNErrorMessage err = SVNErrorMessage
0288:                                        .create(
0289:                                                SVNErrorCode.WC_CORRUPT,
0290:                                                "Missing end of line in wcprops file for ''{0}''",
0291:                                                getRoot());
0292:                                SVNErrorManager.error(err, e);
0293:                            }
0294:                            break;
0295:                        }
0296:                        wcProps = wcpropsFile.readProperties(false);
0297:                        entryWCProps = new SVNProperties13(wcProps);
0298:                        wcPropsCache.put(name, entryWCProps);
0299:                        buffer.delete(0, buffer.length());
0300:                    }
0301:                } catch (SVNException svne) {
0302:                    SVNErrorMessage err = svne.getErrorMessage().wrap(
0303:                            "Failed to load properties from disk");
0304:                    SVNErrorManager.error(err);
0305:                } finally {
0306:                    wcpropsFile.close();
0307:                }
0308:                return wcPropsCache;
0309:            }
0310:
0311:            private Map readBaseProperties(String name) throws SVNException {
0312:                File propertiesFile = getBasePropertiesFile(name, false);
0313:                SVNProperties props = new SVNProperties(propertiesFile, null);
0314:                return props.asMap();
0315:            }
0316:
0317:            private Map readRevertProperties(String name) throws SVNException {
0318:                File propertiesFile = getRevertPropertiesFile(name, false);
0319:                SVNProperties props = new SVNProperties(propertiesFile, null);
0320:                return props.asMap();
0321:            }
0322:
0323:            private Map readProperties(String name) throws SVNException {
0324:                //        SVNEntry entry = getEntry(name, false);        
0325:                if (hasPropModifications(name)
0326:                /*|| (entry != null && entry.isScheduledForReplacement())*/) {
0327:                    // ignore base props when entry is schedule for replacement.
0328:                    File propertiesFile = getPropertiesFile(name, false);
0329:                    SVNProperties props = new SVNProperties(propertiesFile,
0330:                            null);
0331:                    return props.asMap();
0332:                }
0333:
0334:                Map basePropsCache = getBasePropertiesStorage(true);
0335:                if (basePropsCache != null) {
0336:                    SVNVersionedProperties baseProps = (SVNVersionedProperties) basePropsCache
0337:                            .get(name);
0338:                    if (baseProps != null) {
0339:                        return baseProps.asMap();
0340:                    }
0341:                }
0342:                if (hasProperties(name)) {
0343:                    return readBaseProperties(name);
0344:                }
0345:                return new HashMap();
0346:            }
0347:
0348:            public void saveVersionedProperties(SVNLog log, boolean close)
0349:                    throws SVNException {
0350:                Map command = new HashMap();
0351:                Set processedEntries = new HashSet();
0352:
0353:                Map propsCache = getPropertiesStorage(false);
0354:                if (propsCache != null && !propsCache.isEmpty()) {
0355:                    for (Iterator entries = propsCache.keySet().iterator(); entries
0356:                            .hasNext();) {
0357:                        String name = (String) entries.next();
0358:                        SVNVersionedProperties props = (SVNVersionedProperties) propsCache
0359:                                .get(name);
0360:                        if (props.isModified()) {
0361:                            SVNVersionedProperties baseProps = getBaseProperties(name);
0362:                            SVNVersionedProperties propsDiff = baseProps
0363:                                    .compareTo(props);
0364:                            String[] cachableProps = SVNAdminArea14
0365:                                    .getCachableProperties();
0366:                            command.put(SVNProperty.CACHABLE_PROPS, asString(
0367:                                    cachableProps, " "));
0368:                            Map propsMap = props.loadProperties();
0369:                            LinkedList presentProps = new LinkedList();
0370:                            for (int i = 0; i < cachableProps.length; i++) {
0371:                                if (propsMap.containsKey(cachableProps[i])) {
0372:                                    presentProps.addLast(cachableProps[i]);
0373:                                }
0374:                            }
0375:
0376:                            if (presentProps.size() > 0) {
0377:                                String presentPropsString = asString(
0378:                                        (String[]) presentProps
0379:                                                .toArray(new String[presentProps
0380:                                                        .size()]), " ");
0381:                                command.put(SVNProperty.PRESENT_PROPS,
0382:                                        presentPropsString);
0383:                            } else {
0384:                                command.put(SVNProperty.PRESENT_PROPS, "");
0385:                            }
0386:
0387:                            command.put(SVNProperty.HAS_PROPS, SVNProperty
0388:                                    .toString(!props.isEmpty()));
0389:
0390:                            boolean hasPropModifications = !propsDiff.isEmpty();
0391:                            command.put(SVNProperty.HAS_PROP_MODS, SVNProperty
0392:                                    .toString(hasPropModifications));
0393:                            command.put(SVNLog.NAME_ATTR, name);
0394:                            log.addCommand(SVNLog.MODIFY_ENTRY, command, false);
0395:                            processedEntries.add(name);
0396:                            command.clear();
0397:
0398:                            String dstPath = getThisDirName().equals(name) ? "dir-props"
0399:                                    : "props/" + name + ".svn-work";
0400:                            dstPath = getAdminDirectory().getName() + "/"
0401:                                    + dstPath;
0402:
0403:                            if (hasPropModifications) {
0404:                                String tmpPath = "tmp/";
0405:                                tmpPath += getThisDirName().equals(name) ? "dir-props"
0406:                                        : "props/" + name + ".svn-work";
0407:                                File tmpFile = getAdminFile(tmpPath);
0408:                                String srcPath = getAdminDirectory().getName()
0409:                                        + "/" + tmpPath;
0410:                                SVNProperties tmpProps = new SVNProperties(
0411:                                        tmpFile, srcPath);
0412:                                tmpProps.setProperties(props.asMap());
0413:                                command.put(SVNLog.NAME_ATTR, srcPath);
0414:                                command.put(SVNLog.DEST_ATTR, dstPath);
0415:                                log.addCommand(SVNLog.MOVE, command, false);
0416:                                command.clear();
0417:                                command.put(SVNLog.NAME_ATTR, dstPath);
0418:                                log.addCommand(SVNLog.READONLY, command, false);
0419:                            } else {
0420:                                command.put(SVNLog.NAME_ATTR, dstPath);
0421:                                log.addCommand(SVNLog.DELETE, command, false);
0422:                            }
0423:                            command.clear();
0424:                            props.setModified(false);
0425:                        }
0426:                    }
0427:                }
0428:
0429:                Map basePropsCache = getBasePropertiesStorage(false);
0430:                if (basePropsCache != null && !basePropsCache.isEmpty()) {
0431:                    for (Iterator entries = basePropsCache.keySet().iterator(); entries
0432:                            .hasNext();) {
0433:                        String name = (String) entries.next();
0434:                        SVNVersionedProperties baseProps = (SVNVersionedProperties) basePropsCache
0435:                                .get(name);
0436:                        if (baseProps.isModified()) {
0437:                            String dstPath = getThisDirName().equals(name) ? "dir-prop-base"
0438:                                    : "prop-base/" + name + ".svn-base";
0439:                            dstPath = getAdminDirectory().getName() + "/"
0440:                                    + dstPath;
0441:                            boolean isEntryProcessed = processedEntries
0442:                                    .contains(name);
0443:                            if (!isEntryProcessed) {
0444:                                SVNVersionedProperties props = getProperties(name);
0445:
0446:                                String[] cachableProps = SVNAdminArea14
0447:                                        .getCachableProperties();
0448:                                command.put(SVNProperty.CACHABLE_PROPS,
0449:                                        asString(cachableProps, " "));
0450:
0451:                                Map propsMap = props.loadProperties();
0452:                                LinkedList presentProps = new LinkedList();
0453:                                for (int i = 0; i < cachableProps.length; i++) {
0454:                                    if (propsMap.containsKey(cachableProps[i])) {
0455:                                        presentProps.addLast(cachableProps[i]);
0456:                                    }
0457:                                }
0458:
0459:                                if (presentProps.size() > 0) {
0460:                                    String presentPropsString = asString(
0461:                                            (String[]) presentProps
0462:                                                    .toArray(new String[presentProps
0463:                                                            .size()]), " ");
0464:                                    command.put(SVNProperty.PRESENT_PROPS,
0465:                                            presentPropsString);
0466:                                } else {
0467:                                    command.put(SVNProperty.PRESENT_PROPS, "");
0468:                                }
0469:
0470:                                command.put(SVNProperty.HAS_PROPS, SVNProperty
0471:                                        .toString(!props.isEmpty()));
0472:                                SVNVersionedProperties propsDiff = baseProps
0473:                                        .compareTo(props);
0474:                                boolean hasPropModifications = !propsDiff
0475:                                        .isEmpty();
0476:                                command
0477:                                        .put(
0478:                                                SVNProperty.HAS_PROP_MODS,
0479:                                                SVNProperty
0480:                                                        .toString(hasPropModifications));
0481:                                command.put(SVNLog.NAME_ATTR, name);
0482:                                log.addCommand(SVNLog.MODIFY_ENTRY, command,
0483:                                        false);
0484:                                command.clear();
0485:
0486:                                if (!hasPropModifications) {
0487:                                    String workingPropsPath = getThisDirName()
0488:                                            .equals(name) ? "dir-props"
0489:                                            : "props/" + name + ".svn-work";
0490:                                    workingPropsPath = getAdminDirectory()
0491:                                            .getName()
0492:                                            + "/" + workingPropsPath;
0493:                                    command.put(SVNLog.NAME_ATTR,
0494:                                            workingPropsPath);
0495:                                    log.addCommand(SVNLog.DELETE, command,
0496:                                            false);
0497:                                    command.clear();
0498:                                }
0499:                            }
0500:
0501:                            if (baseProps.isEmpty()) {
0502:                                command.put(SVNLog.NAME_ATTR, dstPath);
0503:                                log.addCommand(SVNLog.DELETE, command, false);
0504:                            } else {
0505:                                String tmpPath = "tmp/";
0506:                                tmpPath += getThisDirName().equals(name) ? "dir-prop-base"
0507:                                        : "prop-base/" + name + ".svn-base";
0508:                                File tmpFile = getAdminFile(tmpPath);
0509:                                String srcPath = getAdminDirectory().getName()
0510:                                        + "/" + tmpPath;
0511:                                SVNProperties tmpProps = new SVNProperties(
0512:                                        tmpFile, srcPath);
0513:                                tmpProps.setProperties(baseProps.asMap());
0514:
0515:                                command.put(SVNLog.NAME_ATTR, srcPath);
0516:                                command.put(SVNLog.DEST_ATTR, dstPath);
0517:                                log.addCommand(SVNLog.MOVE, command, false);
0518:                                command.clear();
0519:                                command.put(SVNLog.NAME_ATTR, dstPath);
0520:                                log.addCommand(SVNLog.READONLY, command, false);
0521:                            }
0522:                            baseProps.setModified(false);
0523:                        }
0524:                    }
0525:                }
0526:
0527:                if (close) {
0528:                    closeVersionedProperties();
0529:                }
0530:            }
0531:
0532:            public void saveEntries(boolean close) throws SVNException {
0533:                if (myEntries != null) {
0534:                    if (!isLocked()) {
0535:                        SVNErrorMessage err = SVNErrorMessage.create(
0536:                                SVNErrorCode.WC_NOT_LOCKED,
0537:                                "No write-lock in ''{0}''", getRoot());
0538:                        SVNErrorManager.error(err);
0539:                    }
0540:
0541:                    SVNEntry rootEntry = (SVNEntry) myEntries
0542:                            .get(getThisDirName());
0543:                    if (rootEntry == null) {
0544:                        SVNErrorMessage err = SVNErrorMessage.create(
0545:                                SVNErrorCode.ENTRY_NOT_FOUND,
0546:                                "No default entry in directory ''{0}''",
0547:                                getRoot());
0548:                        SVNErrorManager.error(err);
0549:                    }
0550:
0551:                    String reposURL = rootEntry.getRepositoryRoot();
0552:                    String url = rootEntry.getURL();
0553:                    if (reposURL != null
0554:                            && !SVNPathUtil.isAncestor(reposURL, url)) {
0555:                        SVNErrorMessage err = SVNErrorMessage
0556:                                .create(
0557:                                        SVNErrorCode.UNKNOWN,
0558:                                        "Entry ''{0}'' has inconsistent repository root and url",
0559:                                        getThisDirName());
0560:                        SVNErrorManager.error(err);
0561:                    }
0562:
0563:                    if (ourIsOptimizedWritingEnabled) {
0564:                        File tmpFile = new File(getAdminDirectory(),
0565:                                "tmp/entries");
0566:                        boolean renamed = myEntriesFile.renameTo(tmpFile);
0567:                        if (!renamed) {
0568:                            myEntriesFile.delete();
0569:                            tmpFile = null;
0570:                        }
0571:                        Writer os = null;
0572:                        try {
0573:                            os = new OutputStreamWriter(
0574:                                    new BufferedOutputStream(
0575:                                            new FileOutputStream(myEntriesFile)),
0576:                                    "UTF-8");
0577:                            writeEntries(os);
0578:                        } catch (IOException e) {
0579:                            SVNFileUtil.closeFile(os);
0580:                            if (tmpFile != null) {
0581:                                tmpFile.renameTo(myEntriesFile);
0582:                            }
0583:                            SVNErrorMessage err = SVNErrorMessage.create(
0584:                                    SVNErrorCode.IO_ERROR,
0585:                                    "Cannot write entries file ''{0}'': {1}",
0586:                                    new Object[] { myEntriesFile,
0587:                                            e.getLocalizedMessage() });
0588:                            SVNErrorManager.error(err, e);
0589:                        } finally {
0590:                            SVNFileUtil.closeFile(os);
0591:                            SVNFileUtil.deleteFile(tmpFile);
0592:                        }
0593:                        myEntriesFile.setReadOnly();
0594:                    } else {
0595:                        File tmpFile = new File(getAdminDirectory(),
0596:                                "tmp/entries");
0597:                        Writer os = null;
0598:                        try {
0599:                            os = new OutputStreamWriter(
0600:                                    new BufferedOutputStream(
0601:                                            new FileOutputStream(tmpFile)),
0602:                                    "UTF-8");
0603:                            writeEntries(os);
0604:                        } catch (IOException e) {
0605:                            SVNFileUtil.closeFile(os);
0606:                            SVNFileUtil.deleteFile(tmpFile);
0607:                            SVNErrorMessage err = SVNErrorMessage.create(
0608:                                    SVNErrorCode.IO_ERROR,
0609:                                    "Cannot write entries file ''{0}'': {1}",
0610:                                    new Object[] { myEntriesFile,
0611:                                            e.getMessage() });
0612:                            SVNErrorManager.error(err, e);
0613:                        } finally {
0614:                            SVNFileUtil.closeFile(os);
0615:                        }
0616:                        tmpFile.setReadOnly();
0617:                        SVNFileUtil.rename(tmpFile, myEntriesFile);
0618:                    }
0619:                    if (close) {
0620:                        closeEntries();
0621:                    }
0622:                }
0623:            }
0624:
0625:            protected Map fetchEntries() throws SVNException {
0626:                if (!myEntriesFile.exists()) {
0627:                    return null;
0628:                }
0629:
0630:                Map entries = new HashMap();
0631:                BufferedReader reader = null;
0632:                try {
0633:                    reader = new BufferedReader(new InputStreamReader(
0634:                            SVNFileUtil.openFileForReading(myEntriesFile),
0635:                            "UTF-8"));
0636:                    //skip format line
0637:                    reader.readLine();
0638:                    int entryNumber = 1;
0639:                    while (true) {
0640:                        try {
0641:                            SVNEntry entry = readEntry(reader, entryNumber);
0642:                            if (entry == null) {
0643:                                break;
0644:                            }
0645:                            entries.put(entry.getName(), entry);
0646:                        } catch (SVNException svne) {
0647:                            SVNErrorMessage err = svne
0648:                                    .getErrorMessage()
0649:                                    .wrap(
0650:                                            "Error at entry {0,number,integer} in entries file for ''{1}'':",
0651:                                            new Object[] {
0652:                                                    new Integer(entryNumber),
0653:                                                    getRoot() });
0654:                            SVNErrorManager.error(err);
0655:                        }
0656:                        ++entryNumber;
0657:                    }
0658:                } catch (IOException e) {
0659:                    SVNErrorMessage err = SVNErrorMessage.create(
0660:                            SVNErrorCode.IO_ERROR,
0661:                            "Cannot read entries file ''{0}'': {1}",
0662:                            new Object[] { myEntriesFile, e.getMessage() });
0663:                    SVNErrorManager.error(err, e);
0664:                } finally {
0665:                    SVNFileUtil.closeFile(reader);
0666:                }
0667:
0668:                SVNEntry defaultEntry = (SVNEntry) entries
0669:                        .get(getThisDirName());
0670:                if (defaultEntry == null) {
0671:                    SVNErrorMessage err = SVNErrorMessage.create(
0672:                            SVNErrorCode.ENTRY_NOT_FOUND,
0673:                            "Missing default entry");
0674:                    SVNErrorManager.error(err);
0675:                }
0676:
0677:                Map defaultEntryAttrs = defaultEntry.asMap();
0678:                if (defaultEntryAttrs.get(SVNProperty.REVISION) == null) {
0679:                    SVNErrorMessage err = SVNErrorMessage.create(
0680:                            SVNErrorCode.ENTRY_MISSING_REVISION,
0681:                            "Default entry has no revision number");
0682:                    SVNErrorManager.error(err);
0683:                }
0684:
0685:                if (defaultEntryAttrs.get(SVNProperty.URL) == null) {
0686:                    SVNErrorMessage err = SVNErrorMessage.create(
0687:                            SVNErrorCode.ENTRY_MISSING_URL,
0688:                            "Default entry is missing URL");
0689:                    SVNErrorManager.error(err);
0690:                }
0691:
0692:                for (Iterator entriesIter = entries.keySet().iterator(); entriesIter
0693:                        .hasNext();) {
0694:                    String name = (String) entriesIter.next();
0695:                    SVNEntry entry = (SVNEntry) entries.get(name);
0696:                    if (getThisDirName().equals(name)) {
0697:                        continue;
0698:                    }
0699:
0700:                    Map entryAttributes = entry.asMap();
0701:                    SVNNodeKind kind = SVNNodeKind
0702:                            .parseKind((String) entryAttributes
0703:                                    .get(SVNProperty.KIND));
0704:                    if (kind == SVNNodeKind.FILE) {
0705:                        if (entryAttributes.get(SVNProperty.REVISION) == null
0706:                                || Long.parseLong((String) entryAttributes
0707:                                        .get(SVNProperty.REVISION), 10) < 0) {
0708:                            entryAttributes
0709:                                    .put(SVNProperty.REVISION,
0710:                                            defaultEntryAttrs
0711:                                                    .get(SVNProperty.REVISION));
0712:                        }
0713:                        if (entryAttributes.get(SVNProperty.URL) == null) {
0714:                            String rootURL = (String) defaultEntryAttrs
0715:                                    .get(SVNProperty.URL);
0716:                            String url = SVNPathUtil.append(rootURL,
0717:                                    SVNEncodingUtil.uriEncode(name));
0718:                            entryAttributes.put(SVNProperty.URL, url);
0719:                        }
0720:                        if (entryAttributes.get(SVNProperty.REPOS) == null) {
0721:                            entryAttributes.put(SVNProperty.REPOS,
0722:                                    defaultEntryAttrs.get(SVNProperty.REPOS));
0723:                        }
0724:                        if (entryAttributes.get(SVNProperty.UUID) == null) {
0725:                            String schedule = (String) entryAttributes
0726:                                    .get(SVNProperty.SCHEDULE);
0727:                            if (!(SVNProperty.SCHEDULE_ADD.equals(schedule) || SVNProperty.SCHEDULE_REPLACE
0728:                                    .equals(schedule))) {
0729:                                entryAttributes
0730:                                        .put(SVNProperty.UUID,
0731:                                                defaultEntryAttrs
0732:                                                        .get(SVNProperty.UUID));
0733:                            }
0734:                        }
0735:                        if (entryAttributes.get(SVNProperty.CACHABLE_PROPS) == null) {
0736:                            entryAttributes.put(SVNProperty.CACHABLE_PROPS,
0737:                                    defaultEntryAttrs
0738:                                            .get(SVNProperty.CACHABLE_PROPS));
0739:                        }
0740:                    }
0741:                }
0742:                return entries;
0743:            }
0744:
0745:            private SVNEntry readEntry(BufferedReader reader, int entryNumber)
0746:                    throws IOException, SVNException {
0747:                String line = reader.readLine();
0748:                if (line == null && entryNumber > 1) {
0749:                    return null;
0750:                }
0751:
0752:                String name = parseString(line);
0753:                name = name != null ? name : getThisDirName();
0754:
0755:                Map entryAttrs = new HashMap();
0756:                entryAttrs.put(SVNProperty.NAME, name);
0757:                SVNEntry entry = new SVNEntry(entryAttrs, this , name);
0758:
0759:                line = reader.readLine();
0760:                String kind = parseValue(line);
0761:                if (kind != null) {
0762:                    SVNNodeKind parsedKind = SVNNodeKind.parseKind(kind);
0763:                    if (parsedKind != SVNNodeKind.UNKNOWN
0764:                            && parsedKind != SVNNodeKind.NONE) {
0765:                        entryAttrs.put(SVNProperty.KIND, kind);
0766:                    } else {
0767:                        SVNErrorMessage err = SVNErrorMessage.create(
0768:                                SVNErrorCode.NODE_UNKNOWN_KIND,
0769:                                "Entry ''{0}'' has invalid node kind", name);
0770:                        SVNErrorManager.error(err);
0771:                    }
0772:                } else {
0773:                    entryAttrs.put(SVNProperty.KIND, SVNNodeKind.NONE
0774:                            .toString());
0775:                }
0776:
0777:                line = reader.readLine();
0778:                if (isEntryFinished(line)) {
0779:                    return entry;
0780:                }
0781:                String revision = parseValue(line);
0782:                if (revision != null) {
0783:                    entryAttrs.put(SVNProperty.REVISION, revision);
0784:                }
0785:
0786:                line = reader.readLine();
0787:                if (isEntryFinished(line)) {
0788:                    return entry;
0789:                }
0790:                String url = parseString(line);
0791:                if (url != null) {
0792:                    entryAttrs.put(SVNProperty.URL, url);
0793:                }
0794:
0795:                line = reader.readLine();
0796:                if (isEntryFinished(line)) {
0797:                    return entry;
0798:                }
0799:                String reposRoot = parseString(line);
0800:                if (reposRoot != null && url != null
0801:                        && !SVNPathUtil.isAncestor(reposRoot, url)) {
0802:                    SVNErrorMessage err = SVNErrorMessage.create(
0803:                            SVNErrorCode.WC_CORRUPT,
0804:                            "Entry for ''{0}'' has invalid repository root",
0805:                            name);
0806:                    SVNErrorManager.error(err);
0807:                } else if (reposRoot != null) {
0808:                    entryAttrs.put(SVNProperty.REPOS, reposRoot);
0809:                }
0810:
0811:                line = reader.readLine();
0812:                if (isEntryFinished(line)) {
0813:                    return entry;
0814:                }
0815:                String schedule = parseValue(line);
0816:                if (schedule != null) {
0817:                    if (SVNProperty.SCHEDULE_ADD.equals(schedule)
0818:                            || SVNProperty.SCHEDULE_DELETE.equals(schedule)
0819:                            || SVNProperty.SCHEDULE_REPLACE.equals(schedule)) {
0820:                        entryAttrs.put(SVNProperty.SCHEDULE, schedule);
0821:                    } else {
0822:                        SVNErrorMessage err = SVNErrorMessage.create(
0823:                                SVNErrorCode.ENTRY_ATTRIBUTE_INVALID,
0824:                                "Entry ''{0}'' has invalid ''{1}'' value",
0825:                                new Object[] { name, SVNProperty.SCHEDULE });
0826:                        SVNErrorManager.error(err);
0827:                    }
0828:                }
0829:
0830:                line = reader.readLine();
0831:                if (isEntryFinished(line)) {
0832:                    return entry;
0833:                }
0834:                String timestamp = parseValue(line);
0835:                if (timestamp != null) {
0836:                    entryAttrs.put(SVNProperty.TEXT_TIME, timestamp);
0837:                }
0838:
0839:                line = reader.readLine();
0840:                if (isEntryFinished(line)) {
0841:                    return entry;
0842:                }
0843:                String checksum = parseString(line);
0844:                if (checksum != null) {
0845:                    entryAttrs.put(SVNProperty.CHECKSUM, checksum);
0846:                }
0847:
0848:                line = reader.readLine();
0849:                if (isEntryFinished(line)) {
0850:                    return entry;
0851:                }
0852:                String committedDate = parseValue(line);
0853:                if (committedDate != null) {
0854:                    entryAttrs.put(SVNProperty.COMMITTED_DATE, committedDate);
0855:                }
0856:
0857:                line = reader.readLine();
0858:                if (isEntryFinished(line)) {
0859:                    return entry;
0860:                }
0861:                String committedRevision = parseValue(line);
0862:                if (committedRevision != null) {
0863:                    entryAttrs.put(SVNProperty.COMMITTED_REVISION,
0864:                            committedRevision);
0865:                }
0866:
0867:                line = reader.readLine();
0868:                if (isEntryFinished(line)) {
0869:                    return entry;
0870:                }
0871:                String committedAuthor = parseString(line);
0872:                if (committedAuthor != null) {
0873:                    entryAttrs.put(SVNProperty.LAST_AUTHOR, committedAuthor);
0874:                }
0875:
0876:                line = reader.readLine();
0877:                if (isEntryFinished(line)) {
0878:                    return entry;
0879:                }
0880:                boolean hasProps = parseBoolean(line, SVNProperty.HAS_PROPS);
0881:                if (hasProps) {
0882:                    entryAttrs.put(SVNProperty.HAS_PROPS, SVNProperty
0883:                            .toString(hasProps));
0884:                }
0885:
0886:                line = reader.readLine();
0887:                if (isEntryFinished(line)) {
0888:                    return entry;
0889:                }
0890:                boolean hasPropMods = parseBoolean(line,
0891:                        SVNProperty.HAS_PROP_MODS);
0892:                if (hasPropMods) {
0893:                    entryAttrs.put(SVNProperty.HAS_PROP_MODS, SVNProperty
0894:                            .toString(hasPropMods));
0895:                }
0896:
0897:                line = reader.readLine();
0898:                if (isEntryFinished(line)) {
0899:                    return entry;
0900:                }
0901:                String cachablePropsStr = parseValue(line);
0902:                if (cachablePropsStr != null) {
0903:                    String[] cachableProps = fromString(cachablePropsStr, " ");
0904:                    entryAttrs.put(SVNProperty.CACHABLE_PROPS, cachableProps);
0905:                }
0906:
0907:                line = reader.readLine();
0908:                if (isEntryFinished(line)) {
0909:                    return entry;
0910:                }
0911:                String presentPropsStr = parseValue(line);
0912:                if (presentPropsStr != null) {
0913:                    String[] presentProps = fromString(presentPropsStr, " ");
0914:                    entryAttrs.put(SVNProperty.PRESENT_PROPS, presentProps);
0915:                }
0916:
0917:                line = reader.readLine();
0918:                if (isEntryFinished(line)) {
0919:                    return entry;
0920:                }
0921:                String prejFile = parseString(line);
0922:                if (prejFile != null) {
0923:                    entryAttrs.put(SVNProperty.PROP_REJECT_FILE, prejFile);
0924:                }
0925:
0926:                line = reader.readLine();
0927:                if (isEntryFinished(line)) {
0928:                    return entry;
0929:                }
0930:                String conflictOldFile = parseString(line);
0931:                if (conflictOldFile != null) {
0932:                    entryAttrs.put(SVNProperty.CONFLICT_OLD, conflictOldFile);
0933:                }
0934:
0935:                line = reader.readLine();
0936:                if (isEntryFinished(line)) {
0937:                    return entry;
0938:                }
0939:                String conflictNewFile = parseString(line);
0940:                if (conflictNewFile != null) {
0941:                    entryAttrs.put(SVNProperty.CONFLICT_NEW, conflictNewFile);
0942:                }
0943:
0944:                line = reader.readLine();
0945:                if (isEntryFinished(line)) {
0946:                    return entry;
0947:                }
0948:                String conflictWorkFile = parseString(line);
0949:                if (conflictWorkFile != null) {
0950:                    entryAttrs.put(SVNProperty.CONFLICT_WRK, conflictWorkFile);
0951:                }
0952:
0953:                line = reader.readLine();
0954:                if (isEntryFinished(line)) {
0955:                    return entry;
0956:                }
0957:                boolean isCopied = parseBoolean(line, ATTRIBUTE_COPIED);
0958:                if (isCopied) {
0959:                    entryAttrs.put(SVNProperty.COPIED, SVNProperty
0960:                            .toString(isCopied));
0961:                }
0962:
0963:                line = reader.readLine();
0964:                if (isEntryFinished(line)) {
0965:                    return entry;
0966:                }
0967:                String copyfromURL = parseString(line);
0968:                if (copyfromURL != null) {
0969:                    entryAttrs.put(SVNProperty.COPYFROM_URL, copyfromURL);
0970:                }
0971:
0972:                line = reader.readLine();
0973:                if (isEntryFinished(line)) {
0974:                    return entry;
0975:                }
0976:                String copyfromRevision = parseValue(line);
0977:                if (copyfromRevision != null) {
0978:                    entryAttrs.put(SVNProperty.COPYFROM_REVISION,
0979:                            copyfromRevision);
0980:                }
0981:
0982:                line = reader.readLine();
0983:                if (isEntryFinished(line)) {
0984:                    return entry;
0985:                }
0986:                boolean isDeleted = parseBoolean(line, ATTRIBUTE_DELETED);
0987:                if (isDeleted) {
0988:                    entryAttrs.put(SVNProperty.DELETED, SVNProperty
0989:                            .toString(isDeleted));
0990:                }
0991:
0992:                line = reader.readLine();
0993:                if (isEntryFinished(line)) {
0994:                    return entry;
0995:                }
0996:                boolean isAbsent = parseBoolean(line, ATTRIBUTE_ABSENT);
0997:                if (isAbsent) {
0998:                    entryAttrs.put(SVNProperty.ABSENT, SVNProperty
0999:                            .toString(isAbsent));
1000:                }
1001:
1002:                line = reader.readLine();
1003:                if (isEntryFinished(line)) {
1004:                    return entry;
1005:                }
1006:                boolean isIncomplete = parseBoolean(line, ATTRIBUTE_INCOMPLETE);
1007:                if (isIncomplete) {
1008:                    entryAttrs.put(SVNProperty.INCOMPLETE, SVNProperty
1009:                            .toString(isIncomplete));
1010:                }
1011:
1012:                line = reader.readLine();
1013:                if (isEntryFinished(line)) {
1014:                    return entry;
1015:                }
1016:                String uuid = parseString(line);
1017:                if (uuid != null) {
1018:                    entryAttrs.put(SVNProperty.UUID, uuid);
1019:                }
1020:
1021:                line = reader.readLine();
1022:                if (isEntryFinished(line)) {
1023:                    return entry;
1024:                }
1025:                String lockToken = parseString(line);
1026:                if (lockToken != null) {
1027:                    entryAttrs.put(SVNProperty.LOCK_TOKEN, lockToken);
1028:                }
1029:
1030:                line = reader.readLine();
1031:                if (isEntryFinished(line)) {
1032:                    return entry;
1033:                }
1034:                String lockOwner = parseString(line);
1035:                if (lockOwner != null) {
1036:                    entryAttrs.put(SVNProperty.LOCK_OWNER, lockOwner);
1037:                }
1038:
1039:                line = reader.readLine();
1040:                if (isEntryFinished(line)) {
1041:                    return entry;
1042:                }
1043:                String lockComment = parseString(line);
1044:                if (lockComment != null) {
1045:                    entryAttrs.put(SVNProperty.LOCK_COMMENT, lockComment);
1046:                }
1047:
1048:                line = reader.readLine();
1049:                if (isEntryFinished(line)) {
1050:                    return entry;
1051:                }
1052:                String lockCreationDate = parseValue(line);
1053:                if (lockCreationDate != null) {
1054:                    entryAttrs.put(SVNProperty.LOCK_CREATION_DATE,
1055:                            lockCreationDate);
1056:                }
1057:
1058:                do {
1059:                    line = reader.readLine();
1060:                    if (line == null) {
1061:                        SVNErrorMessage err = SVNErrorMessage.create(
1062:                                SVNErrorCode.WC_CORRUPT,
1063:                                "Missing entry terminator");
1064:                        SVNErrorManager.error(err);
1065:                    } else if (line.length() == 1 && line.charAt(0) == '\f') {
1066:                        break;
1067:                    }
1068:                } while (line != null);
1069:
1070:                return entry;
1071:            }
1072:
1073:            private boolean isEntryFinished(String line) {
1074:                return line != null && line.length() > 0
1075:                        && line.charAt(0) == '\f';
1076:            }
1077:
1078:            private boolean parseBoolean(String line, String field)
1079:                    throws SVNException {
1080:                line = parseValue(line);
1081:                if (line != null) {
1082:                    if (!line.equals(field)) {
1083:                        SVNErrorMessage err = SVNErrorMessage.create(
1084:                                SVNErrorCode.WC_CORRUPT,
1085:                                "Invalid value for field ''{0}''", field);
1086:                        SVNErrorManager.error(err);
1087:                    }
1088:                    return true;
1089:                }
1090:                return false;
1091:            }
1092:
1093:            private String parseString(String line) throws SVNException {
1094:                if (line == null) {
1095:                    SVNErrorMessage err = SVNErrorMessage.create(
1096:                            SVNErrorCode.WC_CORRUPT, "Unexpected end of entry");
1097:                    SVNErrorManager.error(err);
1098:                } else if ("".equals(line)) {
1099:                    return null;
1100:                }
1101:
1102:                int fromIndex = 0;
1103:                int ind = -1;
1104:                StringBuffer buffer = null;
1105:                String escapedString = null;
1106:                while ((ind = line.indexOf('\\', fromIndex)) != -1) {
1107:                    if (line.length() < ind + 4
1108:                            || line.charAt(ind + 1) != 'x'
1109:                            || !SVNEncodingUtil
1110:                                    .isHexDigit(line.charAt(ind + 2))
1111:                            || !SVNEncodingUtil
1112:                                    .isHexDigit(line.charAt(ind + 3))) {
1113:                        SVNErrorMessage err = SVNErrorMessage.create(
1114:                                SVNErrorCode.WC_CORRUPT,
1115:                                "Invalid escape sequence");
1116:                        SVNErrorManager.error(err);
1117:                    }
1118:                    if (buffer == null) {
1119:                        buffer = new StringBuffer();
1120:                    }
1121:
1122:                    escapedString = line.substring(ind + 2, ind + 4);
1123:                    int escapedByte = Integer.parseInt(escapedString, 16);
1124:
1125:                    if (ind > fromIndex) {
1126:                        buffer.append(line.substring(fromIndex, ind));
1127:                        buffer.append((char) (escapedByte & 0xFF));
1128:                    } else {
1129:                        buffer.append((char) (escapedByte & 0xFF));
1130:                    }
1131:                    fromIndex = ind + 4;
1132:                }
1133:
1134:                if (buffer != null) {
1135:                    if (fromIndex < line.length()) {
1136:                        buffer.append(line.substring(fromIndex));
1137:                    }
1138:                    return buffer.toString();
1139:                }
1140:                return line;
1141:            }
1142:
1143:            private String parseValue(String line) throws SVNException {
1144:                if (line == null) {
1145:                    SVNErrorMessage err = SVNErrorMessage.create(
1146:                            SVNErrorCode.WC_CORRUPT, "Unexpected end of entry");
1147:                    SVNErrorManager.error(err);
1148:                } else if ("".equals(line)) {
1149:                    return null;
1150:                }
1151:                return line;
1152:            }
1153:
1154:            public String getThisDirName() {
1155:                return THIS_DIR;
1156:            }
1157:
1158:            protected void writeEntries(Writer writer) throws IOException {
1159:                SVNEntry rootEntry = (SVNEntry) myEntries.get(getThisDirName());
1160:                writer.write(getFormatVersion() + "\n");
1161:                writeEntry(writer, getThisDirName(), rootEntry.asMap(), null);
1162:
1163:                List names = new ArrayList(myEntries.keySet());
1164:                Collections.sort(names);
1165:                for (Iterator entries = names.iterator(); entries.hasNext();) {
1166:                    String name = (String) entries.next();
1167:                    SVNEntry entry = (SVNEntry) myEntries.get(name);
1168:                    if (getThisDirName().equals(name)) {
1169:                        continue;
1170:                    }
1171:
1172:                    Map entryAttributes = entry.asMap();
1173:                    Map defaultEntryAttrs = rootEntry.asMap();
1174:                    SVNNodeKind kind = SVNNodeKind
1175:                            .parseKind((String) entryAttributes
1176:                                    .get(SVNProperty.KIND));
1177:                    if (kind == SVNNodeKind.FILE) {
1178:                        if (entryAttributes.get(SVNProperty.REVISION) == null
1179:                                || Long.parseLong((String) entryAttributes
1180:                                        .get(SVNProperty.REVISION), 10) < 0) {
1181:                            entryAttributes
1182:                                    .put(SVNProperty.REVISION,
1183:                                            defaultEntryAttrs
1184:                                                    .get(SVNProperty.REVISION));
1185:                        }
1186:                        if (entryAttributes.get(SVNProperty.URL) == null) {
1187:                            String rootURL = (String) defaultEntryAttrs
1188:                                    .get(SVNProperty.URL);
1189:                            String url = SVNPathUtil.append(rootURL,
1190:                                    SVNEncodingUtil.uriEncode(name));
1191:                            entryAttributes.put(SVNProperty.URL, url);
1192:                        }
1193:                        if (entryAttributes.get(SVNProperty.REPOS) == null) {
1194:                            entryAttributes.put(SVNProperty.REPOS,
1195:                                    defaultEntryAttrs.get(SVNProperty.REPOS));
1196:                        }
1197:                        if (entryAttributes.get(SVNProperty.UUID) == null) {
1198:                            String schedule = (String) entryAttributes
1199:                                    .get(SVNProperty.SCHEDULE);
1200:                            if (!(SVNProperty.SCHEDULE_ADD.equals(schedule) || SVNProperty.SCHEDULE_REPLACE
1201:                                    .equals(schedule))) {
1202:                                entryAttributes
1203:                                        .put(SVNProperty.UUID,
1204:                                                defaultEntryAttrs
1205:                                                        .get(SVNProperty.UUID));
1206:                            }
1207:                        }
1208:                        if (entryAttributes.get(SVNProperty.CACHABLE_PROPS) == null) {
1209:                            entryAttributes.put(SVNProperty.CACHABLE_PROPS,
1210:                                    defaultEntryAttrs
1211:                                            .get(SVNProperty.CACHABLE_PROPS));
1212:                        }
1213:                    }
1214:
1215:                    writeEntry(writer, name, entryAttributes, rootEntry.asMap());
1216:                }
1217:            }
1218:
1219:            private void writeEntry(Writer writer, String name, Map entry,
1220:                    Map rootEntry) throws IOException {
1221:                boolean isThisDir = getThisDirName().equals(name);
1222:                boolean isSubDir = !isThisDir
1223:                        && SVNProperty.KIND_DIR.equals(entry
1224:                                .get(SVNProperty.KIND));
1225:                int emptyFields = 0;
1226:
1227:                if (!writeString(writer, name, emptyFields)) {
1228:                    ++emptyFields;
1229:                }
1230:
1231:                String kind = (String) entry.get(SVNProperty.KIND);
1232:                if (writeValue(writer, kind, emptyFields)) {
1233:                    emptyFields = 0;
1234:                } else {
1235:                    ++emptyFields;
1236:                }
1237:
1238:                String revision = null;
1239:                if (isThisDir) {
1240:                    revision = (String) entry.get(SVNProperty.REVISION);
1241:                } else if (!isSubDir) {
1242:                    revision = (String) entry.get(SVNProperty.REVISION);
1243:                    if (revision != null
1244:                            && revision.equals(rootEntry
1245:                                    .get(SVNProperty.REVISION))) {
1246:                        revision = null;
1247:                    }
1248:                }
1249:                if (writeRevision(writer, revision, emptyFields)) {
1250:                    emptyFields = 0;
1251:                } else {
1252:                    ++emptyFields;
1253:                }
1254:
1255:                String url = null;
1256:                if (isThisDir) {
1257:                    url = (String) entry.get(SVNProperty.URL);
1258:                } else if (!isSubDir) {
1259:                    url = (String) entry.get(SVNProperty.URL);
1260:                    String expectedURL = SVNPathUtil.append((String) rootEntry
1261:                            .get(SVNProperty.URL), name);
1262:                    if (url != null && url.equals(expectedURL)) {
1263:                        url = null;
1264:                    }
1265:                }
1266:                if (writeString(writer, url, emptyFields)) {
1267:                    emptyFields = 0;
1268:                } else {
1269:                    ++emptyFields;
1270:                }
1271:
1272:                String root = null;
1273:                if (isThisDir) {
1274:                    root = (String) entry.get(SVNProperty.REPOS);
1275:                } else if (!isSubDir) {
1276:                    String this DirRoot = (String) rootEntry
1277:                            .get(SVNProperty.REPOS);
1278:                    root = (String) entry.get(SVNProperty.REPOS);
1279:                    if (root != null && root.equals(this DirRoot)) {
1280:                        root = null;
1281:                    }
1282:                }
1283:                if (writeString(writer, root, emptyFields)) {
1284:                    emptyFields = 0;
1285:                } else {
1286:                    ++emptyFields;
1287:                }
1288:
1289:                String schedule = (String) entry.get(SVNProperty.SCHEDULE);
1290:                if (schedule != null
1291:                        && (!SVNProperty.SCHEDULE_ADD.equals(schedule)
1292:                                && !SVNProperty.SCHEDULE_DELETE
1293:                                        .equals(schedule) && !SVNProperty.SCHEDULE_REPLACE
1294:                                .equals(schedule))) {
1295:                    schedule = null;
1296:                }
1297:                if (writeValue(writer, schedule, emptyFields)) {
1298:                    emptyFields = 0;
1299:                } else {
1300:                    ++emptyFields;
1301:                }
1302:
1303:                String textTime = (String) entry.get(SVNProperty.TEXT_TIME);
1304:                if (writeValue(writer, textTime, emptyFields)) {
1305:                    emptyFields = 0;
1306:                } else {
1307:                    ++emptyFields;
1308:                }
1309:
1310:                String checksum = (String) entry.get(SVNProperty.CHECKSUM);
1311:                if (writeValue(writer, checksum, emptyFields)) {
1312:                    emptyFields = 0;
1313:                } else {
1314:                    ++emptyFields;
1315:                }
1316:
1317:                String committedDate = (String) entry
1318:                        .get(SVNProperty.COMMITTED_DATE);
1319:                if (writeValue(writer, committedDate, emptyFields)) {
1320:                    emptyFields = 0;
1321:                } else {
1322:                    ++emptyFields;
1323:                }
1324:
1325:                String committedRevision = (String) entry
1326:                        .get(SVNProperty.COMMITTED_REVISION);
1327:                if (writeRevision(writer, committedRevision, emptyFields)) {
1328:                    emptyFields = 0;
1329:                } else {
1330:                    ++emptyFields;
1331:                }
1332:
1333:                String committedAuthor = (String) entry
1334:                        .get(SVNProperty.LAST_AUTHOR);
1335:                if (writeString(writer, committedAuthor, emptyFields)) {
1336:                    emptyFields = 0;
1337:                } else {
1338:                    ++emptyFields;
1339:                }
1340:
1341:                String hasProps = (String) entry.get(SVNProperty.HAS_PROPS);
1342:                if (SVNProperty.booleanValue(hasProps)) {
1343:                    writeValue(writer, SVNProperty.HAS_PROPS, emptyFields);
1344:                    emptyFields = 0;
1345:                } else {
1346:                    ++emptyFields;
1347:                }
1348:
1349:                String hasPropMods = (String) entry
1350:                        .get(SVNProperty.HAS_PROP_MODS);
1351:                if (SVNProperty.booleanValue(hasPropMods)) {
1352:                    writeValue(writer, SVNProperty.HAS_PROP_MODS, emptyFields);
1353:                    emptyFields = 0;
1354:                } else {
1355:                    ++emptyFields;
1356:                }
1357:
1358:                String cachableProps = asString((String[]) entry
1359:                        .get(SVNProperty.CACHABLE_PROPS), " ");
1360:                if (!isThisDir) {
1361:                    String this DirCachableProps = asString((String[]) rootEntry
1362:                            .get(SVNProperty.CACHABLE_PROPS), " ");
1363:                    if (this DirCachableProps != null && cachableProps != null
1364:                            && this DirCachableProps.equals(cachableProps)) {
1365:                        cachableProps = null;
1366:                    }
1367:                }
1368:                if (writeValue(writer, cachableProps, emptyFields)) {
1369:                    emptyFields = 0;
1370:                } else {
1371:                    ++emptyFields;
1372:                }
1373:
1374:                String presentProps = asString((String[]) entry
1375:                        .get(SVNProperty.PRESENT_PROPS), " ");
1376:                if (writeValue(writer, presentProps, emptyFields)) {
1377:                    emptyFields = 0;
1378:                } else {
1379:                    ++emptyFields;
1380:                }
1381:
1382:                String propRejectFile = (String) entry
1383:                        .get(SVNProperty.PROP_REJECT_FILE);
1384:                if (writeString(writer, propRejectFile, emptyFields)) {
1385:                    emptyFields = 0;
1386:                } else {
1387:                    ++emptyFields;
1388:                }
1389:
1390:                String conflictOldFile = (String) entry
1391:                        .get(SVNProperty.CONFLICT_OLD);
1392:                if (writeString(writer, conflictOldFile, emptyFields)) {
1393:                    emptyFields = 0;
1394:                } else {
1395:                    ++emptyFields;
1396:                }
1397:
1398:                String conflictNewFile = (String) entry
1399:                        .get(SVNProperty.CONFLICT_NEW);
1400:                if (writeString(writer, conflictNewFile, emptyFields)) {
1401:                    emptyFields = 0;
1402:                } else {
1403:                    ++emptyFields;
1404:                }
1405:
1406:                String conflictWrkFile = (String) entry
1407:                        .get(SVNProperty.CONFLICT_WRK);
1408:                if (writeString(writer, conflictWrkFile, emptyFields)) {
1409:                    emptyFields = 0;
1410:                } else {
1411:                    ++emptyFields;
1412:                }
1413:
1414:                String copiedAttr = (String) entry.get(SVNProperty.COPIED);
1415:                if (SVNProperty.booleanValue(copiedAttr)) {
1416:                    writeValue(writer, ATTRIBUTE_COPIED, emptyFields);
1417:                    emptyFields = 0;
1418:                } else {
1419:                    ++emptyFields;
1420:                }
1421:
1422:                String copyfromURL = (String) entry
1423:                        .get(SVNProperty.COPYFROM_URL);
1424:                if (writeString(writer, copyfromURL, emptyFields)) {
1425:                    emptyFields = 0;
1426:                } else {
1427:                    ++emptyFields;
1428:                }
1429:
1430:                String copyfromRevision = (String) entry
1431:                        .get(SVNProperty.COPYFROM_REVISION);
1432:                if (writeRevision(writer, copyfromRevision, emptyFields)) {
1433:                    emptyFields = 0;
1434:                } else {
1435:                    ++emptyFields;
1436:                }
1437:
1438:                String deletedAttr = (String) entry.get(SVNProperty.DELETED);
1439:                if (SVNProperty.booleanValue(deletedAttr)) {
1440:                    writeValue(writer, ATTRIBUTE_DELETED, emptyFields);
1441:                    emptyFields = 0;
1442:                } else {
1443:                    ++emptyFields;
1444:                }
1445:
1446:                String absentAttr = (String) entry.get(SVNProperty.ABSENT);
1447:                if (SVNProperty.booleanValue(absentAttr)) {
1448:                    writeValue(writer, ATTRIBUTE_ABSENT, emptyFields);
1449:                    emptyFields = 0;
1450:                } else {
1451:                    ++emptyFields;
1452:                }
1453:
1454:                String incompleteAttr = (String) entry
1455:                        .get(SVNProperty.INCOMPLETE);
1456:                if (SVNProperty.booleanValue(incompleteAttr)) {
1457:                    writeValue(writer, ATTRIBUTE_INCOMPLETE, emptyFields);
1458:                    emptyFields = 0;
1459:                } else {
1460:                    ++emptyFields;
1461:                }
1462:
1463:                String uuid = (String) entry.get(SVNProperty.UUID);
1464:                if (!isThisDir) {
1465:                    String this DirUUID = (String) rootEntry
1466:                            .get(SVNProperty.UUID);
1467:                    if (this DirUUID != null && uuid != null
1468:                            && this DirUUID.equals(uuid)) {
1469:                        uuid = null;
1470:                    }
1471:                }
1472:                if (writeValue(writer, uuid, emptyFields)) {
1473:                    emptyFields = 0;
1474:                } else {
1475:                    ++emptyFields;
1476:                }
1477:
1478:                String lockToken = (String) entry.get(SVNProperty.LOCK_TOKEN);
1479:                if (writeString(writer, lockToken, emptyFields)) {
1480:                    emptyFields = 0;
1481:                } else {
1482:                    ++emptyFields;
1483:                }
1484:
1485:                String lockOwner = (String) entry.get(SVNProperty.LOCK_OWNER);
1486:                if (writeString(writer, lockOwner, emptyFields)) {
1487:                    emptyFields = 0;
1488:                } else {
1489:                    ++emptyFields;
1490:                }
1491:
1492:                String lockComment = (String) entry
1493:                        .get(SVNProperty.LOCK_COMMENT);
1494:                if (writeString(writer, lockComment, emptyFields)) {
1495:                    emptyFields = 0;
1496:                } else {
1497:                    ++emptyFields;
1498:                }
1499:
1500:                String lockCreationDate = (String) entry
1501:                        .get(SVNProperty.LOCK_CREATION_DATE);
1502:                writeValue(writer, lockCreationDate, emptyFields);
1503:                writer.write("\f\n");
1504:                writer.flush();
1505:            }
1506:
1507:            private boolean writeString(Writer writer, String str,
1508:                    int emptyFields) throws IOException {
1509:                if (str != null && str.length() > 0) {
1510:                    for (int i = 0; i < emptyFields; i++) {
1511:                        writer.write('\n');
1512:                    }
1513:                    for (int i = 0; i < str.length(); i++) {
1514:                        char ch = str.charAt(i);
1515:                        if (SVNEncodingUtil.isASCIIControlChar(ch)
1516:                                || ch == '\\') {
1517:                            writer.write("\\x");
1518:                            writer.write(SVNFormatUtil
1519:                                    .getHexNumberFromByte((byte) ch));
1520:                        } else {
1521:                            writer.write(ch);
1522:                        }
1523:                    }
1524:                    writer.write('\n');
1525:                    return true;
1526:                }
1527:                return false;
1528:            }
1529:
1530:            private boolean writeValue(Writer writer, String val,
1531:                    int emptyFields) throws IOException {
1532:                if (val != null && val.length() > 0) {
1533:                    for (int i = 0; i < emptyFields; i++) {
1534:                        writer.write('\n');
1535:                    }
1536:                    writer.write(val);
1537:                    writer.write('\n');
1538:                    return true;
1539:                }
1540:                return false;
1541:            }
1542:
1543:            private boolean writeRevision(Writer writer, String rev,
1544:                    int emptyFields) throws IOException {
1545:                if (rev != null && rev.length() > 0 && Long.parseLong(rev) >= 0) {
1546:                    for (int i = 0; i < emptyFields; i++) {
1547:                        writer.write('\n');
1548:                    }
1549:                    writer.write(rev);
1550:                    writer.write('\n');
1551:                    return true;
1552:                }
1553:                return false;
1554:            }
1555:
1556:            public boolean hasPropModifications(String name)
1557:                    throws SVNException {
1558:                SVNEntry entry = getEntry(name, true);
1559:                if (entry != null) {
1560:                    Map entryAttrs = entry.asMap();
1561:                    return SVNProperty.booleanValue((String) entryAttrs
1562:                            .get(SVNProperty.HAS_PROP_MODS));
1563:                }
1564:                return false;
1565:            }
1566:
1567:            public boolean hasProperties(String name) throws SVNException {
1568:                SVNEntry entry = getEntry(name, true);
1569:                if (entry != null) {
1570:                    Map entryAttrs = entry.asMap();
1571:                    return SVNProperty.booleanValue((String) entryAttrs
1572:                            .get(SVNProperty.HAS_PROPS));
1573:                }
1574:                return false;
1575:            }
1576:
1577:            public boolean lock() throws SVNException {
1578:                return lock(false);
1579:            }
1580:
1581:            public boolean lock(boolean stealLock) throws SVNException {
1582:                if (!isVersioned()) {
1583:                    return false;
1584:                }
1585:                if (stealLock && myLockFile.isFile()) {
1586:                    setLocked(true);
1587:                    return true;
1588:                }
1589:                boolean created = false;
1590:                try {
1591:                    created = myLockFile.createNewFile();
1592:                } catch (IOException e) {
1593:                    SVNErrorCode code = e.getMessage().indexOf("denied") >= 0 ? SVNErrorCode.WC_LOCKED
1594:                            : SVNErrorCode.WC_NOT_LOCKED;
1595:                    SVNErrorMessage err = SVNErrorMessage
1596:                            .create(code,
1597:                                    "Cannot lock working copy ''{0}'': {1}",
1598:                                    new Object[] { getRoot(),
1599:                                            e.getLocalizedMessage() });
1600:                    SVNErrorManager.error(err, e);
1601:                }
1602:                if (created) {
1603:                    setLocked(true);
1604:                    return created;
1605:                }
1606:                if (myLockFile.isFile()) {
1607:                    SVNErrorMessage err = SVNErrorMessage
1608:                            .create(
1609:                                    SVNErrorCode.WC_LOCKED,
1610:                                    "Working copy ''{0}'' locked; try performing ''cleanup''",
1611:                                    getRoot());
1612:                    SVNErrorManager.error(err);
1613:                } else {
1614:                    SVNErrorMessage err = SVNErrorMessage.create(
1615:                            SVNErrorCode.WC_NOT_LOCKED,
1616:                            "Cannot lock working copy ''{0}''", getRoot());
1617:                    SVNErrorManager.error(err);
1618:                }
1619:                return false;
1620:            }
1621:
1622:            private void createFormatFile(File formatFile, boolean createMyself)
1623:                    throws SVNException {
1624:                OutputStream os = null;
1625:                try {
1626:                    formatFile = createMyself ? getAdminFile("format")
1627:                            : formatFile;
1628:                    os = SVNFileUtil.openFileForWriting(formatFile);
1629:                    os.write(String.valueOf(WC_FORMAT).getBytes("UTF-8"));
1630:                    os.write('\n');
1631:                } catch (IOException e) {
1632:                    SVNErrorMessage err = SVNErrorMessage.create(
1633:                            SVNErrorCode.IO_ERROR, e.getLocalizedMessage());
1634:                    SVNErrorManager.error(err, e);
1635:                } finally {
1636:                    SVNFileUtil.closeFile(os);
1637:                }
1638:            }
1639:
1640:            public SVNAdminArea createVersionedDirectory(File dir, String url,
1641:                    String rootURL, String uuid, long revNumber,
1642:                    boolean createMyself) throws SVNException {
1643:                dir = createMyself ? getRoot() : dir;
1644:                dir.mkdirs();
1645:                File adminDir = createMyself ? getAdminDirectory() : new File(
1646:                        dir, SVNFileUtil.getAdminDirectoryName());
1647:                adminDir.mkdir();
1648:                SVNFileUtil.setHidden(adminDir, true);
1649:                // lock dir.
1650:                File lockFile = createMyself ? myLockFile : new File(adminDir,
1651:                        "lock");
1652:                SVNFileUtil.createEmptyFile(lockFile);
1653:
1654:                File[] tmp = {
1655:                        createMyself ? getAdminFile("tmp") : new File(adminDir,
1656:                                "tmp"),
1657:                        createMyself ? getAdminFile("tmp" + File.separatorChar
1658:                                + "props") : new File(adminDir, "tmp"
1659:                                + File.separatorChar + "props"),
1660:                        createMyself ? getAdminFile("tmp" + File.separatorChar
1661:                                + "prop-base") : new File(adminDir, "tmp"
1662:                                + File.separatorChar + "prop-base"),
1663:                        createMyself ? getAdminFile("tmp" + File.separatorChar
1664:                                + "text-base") : new File(adminDir, "tmp"
1665:                                + File.separatorChar + "text-base"),
1666:                        createMyself ? getAdminFile("props") : new File(
1667:                                adminDir, "props"),
1668:                        createMyself ? getAdminFile("prop-base") : new File(
1669:                                adminDir, "prop-base"),
1670:                        createMyself ? getAdminFile("text-base") : new File(
1671:                                adminDir, "text-base") };
1672:
1673:                for (int i = 0; i < tmp.length; i++) {
1674:                    tmp[i].mkdir();
1675:                }
1676:                // for backward compatibility 
1677:                createFormatFile(createMyself ? null : new File(adminDir,
1678:                        "format"), createMyself);
1679:
1680:                SVNAdminArea adminArea = createMyself ? this 
1681:                        : new SVNAdminArea14(dir);
1682:                adminArea.setLocked(true);
1683:                SVNEntry rootEntry = adminArea.getEntry(adminArea
1684:                        .getThisDirName(), true);
1685:                if (rootEntry == null) {
1686:                    rootEntry = adminArea.addEntry(adminArea.getThisDirName());
1687:                }
1688:                if (url != null) {
1689:                    rootEntry.setURL(url);
1690:                }
1691:                rootEntry.setRepositoryRoot(rootURL);
1692:                rootEntry.setRevision(revNumber);
1693:                rootEntry.setKind(SVNNodeKind.DIR);
1694:                if (uuid != null) {
1695:                    rootEntry.setUUID(uuid);
1696:                }
1697:                if (revNumber > 0) {
1698:                    rootEntry.setIncomplete(true);
1699:                }
1700:                rootEntry.setCachableProperties(ourCachableProperties);
1701:                try {
1702:                    adminArea.saveEntries(false);
1703:                } catch (SVNException svne) {
1704:                    SVNErrorMessage err = svne.getErrorMessage().wrap(
1705:                            "Error writing entries file for ''{0}''", dir);
1706:                    SVNErrorManager.error(err, svne);
1707:                }
1708:
1709:                // unlock dir.
1710:                SVNFileUtil.deleteFile(lockFile);
1711:                return adminArea;
1712:            }
1713:
1714:            public SVNAdminArea upgradeFormat(SVNAdminArea adminArea)
1715:                    throws SVNException {
1716:                File logFile = adminArea.getAdminFile("log");
1717:                SVNFileType type = SVNFileType.getType(logFile);
1718:                if (type == SVNFileType.FILE) {
1719:                    SVNDebugLog.getDefaultLog().info(
1720:                            "Upgrade failed: found a log file at '" + logFile
1721:                                    + "'");
1722:                    return adminArea;
1723:                }
1724:
1725:                SVNLog log = getLog();
1726:                Map command = new HashMap();
1727:                command.put(SVNLog.FORMAT_ATTR, String
1728:                        .valueOf(getFormatVersion()));
1729:                log.addCommand(SVNLog.UPGRADE_FORMAT, command, false);
1730:                command.clear();
1731:
1732:                setWCAccess(adminArea.getWCAccess());
1733:                Iterator entries = adminArea.entries(true);
1734:                myEntries = new HashMap();
1735:                Map basePropsCache = getBasePropertiesStorage(true);
1736:                Map propsCache = getPropertiesStorage(true);
1737:
1738:                for (; entries.hasNext();) {
1739:                    SVNEntry entry = (SVNEntry) entries.next();
1740:                    SVNEntry newEntry = new SVNEntry(
1741:                            new HashMap(entry.asMap()), this , entry.getName());
1742:                    myEntries.put(entry.getName(), newEntry);
1743:
1744:                    if (entry.getKind() != SVNNodeKind.FILE
1745:                            && !adminArea.getThisDirName().equals(
1746:                                    entry.getName())) {
1747:                        continue;
1748:                    }
1749:
1750:                    SVNVersionedProperties srcBaseProps = adminArea
1751:                            .getBaseProperties(entry.getName());
1752:                    Map basePropsHolder = srcBaseProps.asMap();
1753:                    SVNVersionedProperties dstBaseProps = new SVNProperties13(
1754:                            basePropsHolder);
1755:                    basePropsCache.put(entry.getName(), dstBaseProps);
1756:                    dstBaseProps.setModified(true);
1757:
1758:                    SVNVersionedProperties srcProps = adminArea
1759:                            .getProperties(entry.getName());
1760:                    SVNVersionedProperties dstProps = new SVNProperties14(
1761:                            srcProps.asMap(), this , entry.getName()) {
1762:
1763:                        protected Map loadProperties() throws SVNException {
1764:                            return getPropertiesMap();
1765:                        }
1766:                    };
1767:                    propsCache.put(entry.getName(), dstProps);
1768:                    dstProps.setModified(true);
1769:
1770:                    command.put(SVNLog.NAME_ATTR, entry.getName());
1771:                    command.put(SVNProperty
1772:                            .shortPropertyName(SVNProperty.PROP_TIME),
1773:                            SVNTimeUtil.formatDate(new Date(0), true));
1774:                    log.addCommand(SVNLog.MODIFY_ENTRY, command, false);
1775:                    command.clear();
1776:
1777:                    SVNVersionedProperties wcProps = adminArea
1778:                            .getWCProperties(entry.getName());
1779:                    log
1780:                            .logChangedWCProperties(entry.getName(), wcProps
1781:                                    .asMap());
1782:                }
1783:                saveVersionedProperties(log, true);
1784:                log.save();
1785:
1786:                SVNFileUtil.deleteFile(getAdminFile("README.txt"));
1787:                SVNFileUtil.deleteFile(getAdminFile("empty-file"));
1788:                SVNFileUtil.deleteAll(getAdminFile("wcprops"), true);
1789:                SVNFileUtil.deleteAll(getAdminFile("tmp/wcprops"), true);
1790:                SVNFileUtil.deleteAll(getAdminFile("dir-wcprops"), true);
1791:
1792:                runLogs();
1793:                return this ;
1794:            }
1795:
1796:            public void postUpgradeFormat(int format) throws SVNException {
1797:                if (format == WC_FORMAT) {
1798:                    createFormatFile(null, true);
1799:                    return;
1800:                }
1801:                SVNErrorMessage err = SVNErrorMessage.create(
1802:                        SVNErrorCode.UNKNOWN, "Unexpected format number:\n"
1803:                                + "   expected: {0,number,integer}\n"
1804:                                + "     actual: {1,number,integer}",
1805:                        new Object[] { new Integer(WC_FORMAT),
1806:                                new Integer(format) });
1807:                SVNErrorManager.error(err);
1808:            }
1809:
1810:            public void postCommit(String fileName, long revisionNumber,
1811:                    boolean implicit, SVNErrorCode errorCode)
1812:                    throws SVNException {
1813:                SVNEntry entry = getEntry(fileName, true);
1814:                if (entry == null
1815:                        || (!getThisDirName().equals(fileName) && entry
1816:                                .getKind() != SVNNodeKind.FILE)) {
1817:                    SVNErrorMessage err = SVNErrorMessage.create(errorCode,
1818:                            "Log command for directory ''{0}'' is mislocated",
1819:                            getRoot());
1820:                    SVNErrorManager.error(err);
1821:                }
1822:
1823:                if (!implicit && entry.isScheduledForDeletion()) {
1824:                    if (getThisDirName().equals(fileName)) {
1825:                        entry.setRevision(revisionNumber);
1826:                        entry.setKind(SVNNodeKind.DIR);
1827:                        File killMe = getAdminFile("KILLME");
1828:                        if (killMe.getParentFile().isDirectory()) {
1829:                            try {
1830:                                killMe.createNewFile();
1831:                            } catch (IOException e) {
1832:                                SVNErrorMessage err = SVNErrorMessage.create(
1833:                                        SVNErrorCode.IO_ERROR,
1834:                                        "Cannot create file ''{0}'': {1}",
1835:                                        new Object[] { killMe,
1836:                                                e.getLocalizedMessage() });
1837:                                SVNErrorManager.error(err, e);
1838:                            }
1839:                        }
1840:                    } else {
1841:                        removeFromRevisionControl(fileName, false, false);
1842:                        SVNEntry parentEntry = getEntry(getThisDirName(), true);
1843:                        if (revisionNumber > parentEntry.getRevision()) {
1844:                            SVNEntry fileEntry = addEntry(fileName);
1845:                            fileEntry.setKind(SVNNodeKind.FILE);
1846:                            fileEntry.setDeleted(true);
1847:                            fileEntry.setRevision(revisionNumber);
1848:                        }
1849:                    }
1850:                    return;
1851:                }
1852:
1853:                if (!implicit && entry.isScheduledForReplacement()
1854:                        && getThisDirName().equals(fileName)) {
1855:                    for (Iterator ents = entries(true); ents.hasNext();) {
1856:                        SVNEntry currentEntry = (SVNEntry) ents.next();
1857:                        if (!currentEntry.isScheduledForDeletion()) {
1858:                            continue;
1859:                        }
1860:                        if (currentEntry.getKind() == SVNNodeKind.FILE
1861:                                || currentEntry.getKind() == SVNNodeKind.DIR) {
1862:                            removeFromRevisionControl(currentEntry.getName(),
1863:                                    false, false);
1864:                        }
1865:                    }
1866:                }
1867:
1868:                long textTime = 0;
1869:                if (!implicit && !getThisDirName().equals(fileName)) {
1870:                    File tmpFile = getBaseFile(fileName, true);
1871:                    SVNFileType fileType = SVNFileType.getType(tmpFile);
1872:                    if (fileType == SVNFileType.FILE
1873:                            || fileType == SVNFileType.SYMLINK) {
1874:                        boolean modified = false;
1875:                        File workingFile = getFile(fileName);
1876:                        long tmpTimestamp = tmpFile.lastModified();
1877:                        long wkTimestamp = workingFile.lastModified();
1878:                        if (tmpTimestamp != wkTimestamp) {
1879:                            // check if wc file is not modified
1880:                            File tmpFile2 = SVNFileUtil.createUniqueFile(
1881:                                    tmpFile.getParentFile(), fileName, ".tmp");
1882:                            try {
1883:                                String tmpFile2Path = SVNFileUtil
1884:                                        .getBasePath(tmpFile2);
1885:                                SVNTranslator.translate(this , fileName,
1886:                                        fileName, tmpFile2Path, false);
1887:                                modified = !SVNFileUtil.compareFiles(tmpFile,
1888:                                        tmpFile2, null);
1889:                            } catch (SVNException svne) {
1890:                                SVNErrorMessage err = SVNErrorMessage.create(
1891:                                        errorCode,
1892:                                        "Error comparing ''{0}'' and ''{1}''",
1893:                                        new Object[] { workingFile, tmpFile });
1894:                                SVNErrorManager.error(err, svne);
1895:                            } finally {
1896:                                tmpFile2.delete();
1897:                            }
1898:                        }
1899:
1900:                        textTime = modified ? tmpTimestamp : wkTimestamp;
1901:                    }
1902:                }
1903:                if (!implicit && entry.isScheduledForReplacement()) {
1904:                    SVNFileUtil.deleteFile(getBasePropertiesFile(fileName,
1905:                            false));
1906:                }
1907:
1908:                boolean setReadWrite = false;
1909:                boolean setNotExecutable = false;
1910:                SVNVersionedProperties baseProps = getBaseProperties(fileName);
1911:                SVNVersionedProperties wcProps = getProperties(fileName);
1912:
1913:                //TODO: to work properly we must create a tmp working props file
1914:                //instead of tmp base props one
1915:                File tmpPropsFile = getPropertiesFile(fileName, true);
1916:                File wcPropsFile = getPropertiesFile(fileName, false);
1917:                File basePropertiesFile = getBasePropertiesFile(fileName, false);
1918:                SVNFileType tmpPropsType = SVNFileType.getType(tmpPropsFile);
1919:                // tmp may be missing when there were no prop change at all!
1920:                if (tmpPropsType == SVNFileType.FILE) {
1921:                    if (!getThisDirName().equals(fileName)) {
1922:                        SVNVersionedProperties propDiff = baseProps
1923:                                .compareTo(wcProps);
1924:                        setReadWrite = propDiff != null
1925:                                && propDiff
1926:                                        .containsProperty(SVNProperty.NEEDS_LOCK)
1927:                                && propDiff
1928:                                        .getPropertyValue(SVNProperty.NEEDS_LOCK) == null;
1929:                        setNotExecutable = propDiff != null
1930:                                && propDiff
1931:                                        .containsProperty(SVNProperty.EXECUTABLE)
1932:                                && propDiff
1933:                                        .getPropertyValue(SVNProperty.EXECUTABLE) == null;
1934:                    }
1935:                    try {
1936:                        if (!tmpPropsFile.exists()
1937:                                || tmpPropsFile.length() <= 4) {
1938:                            SVNFileUtil.deleteFile(basePropertiesFile);
1939:                        } else {
1940:                            SVNFileUtil.copyFile(tmpPropsFile,
1941:                                    basePropertiesFile, true);
1942:                            SVNFileUtil.setReadonly(basePropertiesFile, true);
1943:                        }
1944:                    } finally {
1945:                        SVNFileUtil.deleteFile(tmpPropsFile);
1946:                    }
1947:                }
1948:
1949:                if (!getThisDirName().equals(fileName) && !implicit) {
1950:                    File tmpFile = getBaseFile(fileName, true);
1951:                    File baseFile = getBaseFile(fileName, false);
1952:                    File wcFile = getFile(fileName);
1953:                    File tmpFile2 = null;
1954:                    try {
1955:                        tmpFile2 = SVNFileUtil.createUniqueFile(tmpFile
1956:                                .getParentFile(), fileName, ".tmp");
1957:                        boolean overwritten = false;
1958:                        SVNFileType fileType = SVNFileType.getType(tmpFile);
1959:                        boolean special = getProperties(fileName)
1960:                                .getPropertyValue(SVNProperty.SPECIAL) != null;
1961:                        if (SVNFileUtil.isWindows || !special) {
1962:                            if (fileType == SVNFileType.FILE) {
1963:                                SVNTranslator
1964:                                        .translate(this , fileName, SVNFileUtil
1965:                                                .getBasePath(tmpFile),
1966:                                                SVNFileUtil
1967:                                                        .getBasePath(tmpFile2),
1968:                                                true);
1969:                            } else {
1970:                                SVNTranslator.translate(this , fileName,
1971:                                        fileName, SVNFileUtil
1972:                                                .getBasePath(tmpFile2), true);
1973:                            }
1974:                            if (!SVNFileUtil.compareFiles(tmpFile2, wcFile,
1975:                                    null)) {
1976:                                SVNFileUtil.copyFile(tmpFile2, wcFile, true);
1977:                                overwritten = true;
1978:                            }
1979:                        }
1980:                        boolean needsReadonly = getProperties(fileName)
1981:                                .getPropertyValue(SVNProperty.NEEDS_LOCK) != null
1982:                                && entry.getLockToken() == null;
1983:                        boolean needsExecutable = getProperties(fileName)
1984:                                .getPropertyValue(SVNProperty.EXECUTABLE) != null;
1985:                        if (needsReadonly) {
1986:                            SVNFileUtil.setReadonly(wcFile, true);
1987:                            overwritten = true;
1988:                        }
1989:                        if (needsExecutable) {
1990:                            SVNFileUtil.setExecutable(wcFile, true);
1991:                            overwritten = true;
1992:                        }
1993:                        if (fileType == SVNFileType.FILE) {
1994:                            SVNFileUtil.rename(tmpFile, baseFile);
1995:                        }
1996:                        if (setReadWrite) {
1997:                            SVNFileUtil.setReadonly(wcFile, false);
1998:                            overwritten = true;
1999:                        }
2000:                        if (setNotExecutable) {
2001:                            SVNFileUtil.setExecutable(wcFile, false);
2002:                            overwritten = true;
2003:                        }
2004:                        if (overwritten) {
2005:                            textTime = wcFile.lastModified();
2006:                        }
2007:                    } catch (SVNException svne) {
2008:                        SVNErrorMessage err = SVNErrorMessage.create(errorCode,
2009:                                "Error replacing text-base of ''{0}''",
2010:                                fileName);
2011:                        SVNErrorManager.error(err, svne);
2012:                    } finally {
2013:                        tmpFile2.delete();
2014:                        tmpFile.delete();
2015:                    }
2016:                }
2017:
2018:                // update entry
2019:                Map entryAttrs = new HashMap();
2020:                entryAttrs.put(SVNProperty
2021:                        .shortPropertyName(SVNProperty.REVISION), SVNProperty
2022:                        .toString(revisionNumber));
2023:                entryAttrs
2024:                        .put(
2025:                                SVNProperty.shortPropertyName(SVNProperty.KIND),
2026:                                getThisDirName().equals(fileName) ? SVNProperty.KIND_DIR
2027:                                        : SVNProperty.KIND_FILE);
2028:                if (!implicit) {
2029:                    entryAttrs.put(SVNProperty
2030:                            .shortPropertyName(SVNProperty.SCHEDULE), null);
2031:                }
2032:                entryAttrs.put(SVNProperty
2033:                        .shortPropertyName(SVNProperty.COPIED), SVNProperty
2034:                        .toString(false));
2035:                entryAttrs.put(SVNProperty
2036:                        .shortPropertyName(SVNProperty.DELETED), SVNProperty
2037:                        .toString(false));
2038:                if (textTime != 0 && !implicit) {
2039:                    entryAttrs.put(SVNProperty
2040:                            .shortPropertyName(SVNProperty.TEXT_TIME),
2041:                            SVNTimeUtil.formatDate(new Date(textTime)));
2042:                }
2043:                entryAttrs.put(SVNProperty
2044:                        .shortPropertyName(SVNProperty.CONFLICT_NEW), null);
2045:                entryAttrs.put(SVNProperty
2046:                        .shortPropertyName(SVNProperty.CONFLICT_OLD), null);
2047:                entryAttrs.put(SVNProperty
2048:                        .shortPropertyName(SVNProperty.CONFLICT_WRK), null);
2049:                entryAttrs.put(SVNProperty
2050:                        .shortPropertyName(SVNProperty.PROP_REJECT_FILE), null);
2051:                entryAttrs
2052:                        .put(
2053:                                SVNProperty
2054:                                        .shortPropertyName(SVNProperty.COPYFROM_REVISION),
2055:                                null);
2056:                entryAttrs.put(SVNProperty
2057:                        .shortPropertyName(SVNProperty.COPYFROM_URL), null);
2058:                entryAttrs.put(SVNProperty
2059:                        .shortPropertyName(SVNProperty.HAS_PROP_MODS),
2060:                        SVNProperty.toString(false));
2061:
2062:                try {
2063:                    modifyEntry(fileName, entryAttrs, false, true);
2064:                } catch (SVNException svne) {
2065:                    SVNErrorMessage err = SVNErrorMessage.create(errorCode,
2066:                            "Error modifying entry of ''{0}''", fileName);
2067:                    SVNErrorManager.error(err, svne);
2068:                }
2069:                SVNFileUtil.deleteFile(wcPropsFile);
2070:
2071:                if (!getThisDirName().equals(fileName)) {
2072:                    return;
2073:                }
2074:                // update entry in parent.
2075:                File dirFile = getRoot();
2076:                if (getWCAccess().isWCRoot(getRoot())) {
2077:                    return;
2078:                }
2079:
2080:                boolean unassociated = false;
2081:                SVNAdminArea parentArea = null;
2082:                try {
2083:                    parentArea = getWCAccess()
2084:                            .retrieve(dirFile.getParentFile());
2085:                } catch (SVNException svne) {
2086:                    if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.WC_NOT_LOCKED) {
2087:                        parentArea = getWCAccess().open(
2088:                                dirFile.getParentFile(), true, false, 0);
2089:                        unassociated = true;
2090:                    }
2091:                    throw svne;
2092:                }
2093:
2094:                SVNEntry entryInParent = parentArea.getEntry(dirFile.getName(),
2095:                        false);
2096:                if (entryInParent != null) {
2097:                    entryAttrs.clear();
2098:
2099:                    if (!implicit) {
2100:                        entryAttrs.put(SVNProperty
2101:                                .shortPropertyName(SVNProperty.SCHEDULE), null);
2102:                    }
2103:                    entryAttrs.put(SVNProperty
2104:                            .shortPropertyName(SVNProperty.COPIED), SVNProperty
2105:                            .toString(false));
2106:                    entryAttrs.put(SVNProperty
2107:                            .shortPropertyName(SVNProperty.COPYFROM_REVISION),
2108:                            null);
2109:                    entryAttrs.put(SVNProperty
2110:                            .shortPropertyName(SVNProperty.COPYFROM_URL), null);
2111:                    entryAttrs.put(SVNProperty
2112:                            .shortPropertyName(SVNProperty.DELETED),
2113:                            SVNProperty.toString(false));
2114:                    try {
2115:                        parentArea.modifyEntry(entryInParent.getName(),
2116:                                entryAttrs, true, true);
2117:                    } catch (SVNException svne) {
2118:                        SVNErrorMessage err = SVNErrorMessage.create(errorCode,
2119:                                "Error modifying entry of ''{0}''", fileName);
2120:                        SVNErrorManager.error(err, svne);
2121:                    }
2122:                }
2123:                parentArea.saveEntries(false);
2124:
2125:                if (unassociated) {
2126:                    getWCAccess().closeAdminArea(dirFile.getParentFile());
2127:                }
2128:            }
2129:
2130:            public boolean unlock() throws SVNException {
2131:                if (!myLockFile.exists()) {
2132:                    return true;
2133:                }
2134:                // only if there are not locks or killme files.
2135:                boolean killMe = getAdminFile("KILLME").exists();
2136:                if (killMe) {
2137:                    return false;
2138:                }
2139:                File[] logs = SVNFileListUtil.listFiles(getAdminDirectory());
2140:                for (int i = 0; logs != null && i < logs.length; i++) {
2141:                    File log = logs[i];
2142:                    if ("log".equals(log.getName())
2143:                            || log.getName().startsWith("log.")) {
2144:                        return false;
2145:                    }
2146:                }
2147:                boolean deleted = SVNFileUtil.deleteFile(myLockFile);
2148:                if (!deleted) {
2149:                    SVNErrorMessage err = SVNErrorMessage.create(
2150:                            SVNErrorCode.WC_LOCKED,
2151:                            "Failed to unlock working copy ''{0}''", getRoot());
2152:                    SVNErrorManager.error(err);
2153:                }
2154:                return deleted;
2155:            }
2156:
2157:            public boolean isVersioned() {
2158:                if (getAdminDirectory().isDirectory()
2159:                        && myEntriesFile.canRead()) {
2160:                    try {
2161:                        if (getEntry("", false) != null) {
2162:                            return true;
2163:                        }
2164:                    } catch (SVNException e) {
2165:                        //
2166:                    }
2167:                }
2168:                return false;
2169:            }
2170:
2171:            public boolean isLocked() throws SVNException {
2172:                if (!myWasLocked) {
2173:                    return false;
2174:                }
2175:                SVNFileType type = SVNFileType.getType(myLockFile);
2176:                if (type == SVNFileType.FILE) {
2177:                    return true;
2178:                } else if (type == SVNFileType.NONE) {
2179:                    return false;
2180:                }
2181:
2182:                SVNErrorMessage err = SVNErrorMessage.create(
2183:                        SVNErrorCode.WC_LOCKED,
2184:                        "Lock file ''{0}'' is not a regular file", myLockFile);
2185:                SVNErrorManager.error(err);
2186:                return false;
2187:            }
2188:
2189:            protected int getFormatVersion() {
2190:                return WC_FORMAT;
2191:            }
2192:
2193:            protected boolean isEntryPropertyApplicable(String name) {
2194:                return true;
2195:            }
2196:
2197:        }
w__ww___.__ja__v__a___2___s.co__m | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.