Source Code Cross Referenced for SVNAdminArea.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.File;
0015:        import java.io.IOException;
0016:        import java.io.InputStream;
0017:        import java.io.OutputStream;
0018:        import java.io.Writer;
0019:        import java.text.MessageFormat;
0020:        import java.util.ArrayList;
0021:        import java.util.Collection;
0022:        import java.util.Collections;
0023:        import java.util.Date;
0024:        import java.util.HashMap;
0025:        import java.util.Iterator;
0026:        import java.util.LinkedList;
0027:        import java.util.List;
0028:        import java.util.Map;
0029:
0030:        import org.tmatesoft.svn.core.SVNCancelException;
0031:        import org.tmatesoft.svn.core.SVNCommitInfo;
0032:        import org.tmatesoft.svn.core.SVNErrorCode;
0033:        import org.tmatesoft.svn.core.SVNErrorMessage;
0034:        import org.tmatesoft.svn.core.SVNException;
0035:        import org.tmatesoft.svn.core.SVNNodeKind;
0036:        import org.tmatesoft.svn.core.SVNProperty;
0037:        import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
0038:        import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
0039:        import org.tmatesoft.svn.core.internal.util.SVNTimeUtil;
0040:        import org.tmatesoft.svn.core.internal.wc.DefaultSVNMerger;
0041:        import org.tmatesoft.svn.core.internal.wc.SVNAdminUtil;
0042:        import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
0043:        import org.tmatesoft.svn.core.internal.wc.SVNFileType;
0044:        import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
0045:        import org.tmatesoft.svn.core.internal.wc.SVNPropertiesManager;
0046:        import org.tmatesoft.svn.core.wc.ISVNCommitParameters;
0047:        import org.tmatesoft.svn.core.wc.ISVNMerger;
0048:        import org.tmatesoft.svn.core.wc.ISVNMergerFactory;
0049:        import org.tmatesoft.svn.core.wc.SVNDiffOptions;
0050:        import org.tmatesoft.svn.core.wc.SVNRevision;
0051:        import org.tmatesoft.svn.core.wc.SVNStatusType;
0052:        import org.tmatesoft.svn.util.SVNDebugLog;
0053:
0054:        /**
0055:         * @version 1.1.1
0056:         * @author  TMate Software Ltd.
0057:         */
0058:        public abstract class SVNAdminArea {
0059:
0060:            private static volatile boolean ourIsCleanupSafe;
0061:
0062:            private File myDirectory;
0063:            private SVNWCAccess myWCAccess;
0064:            private File myAdminRoot;
0065:            protected Map myBaseProperties;
0066:            protected Map myProperties;
0067:            protected Map myWCProperties;
0068:            protected Map myEntries;
0069:            private Map myRevertProperties;
0070:
0071:            protected boolean myWasLocked;
0072:            private ISVNCommitParameters myCommitParameters;
0073:
0074:            public static synchronized void setSafeCleanup(boolean safe) {
0075:                ourIsCleanupSafe = safe;
0076:            }
0077:
0078:            public static synchronized boolean isSafeCleanup() {
0079:                return ourIsCleanupSafe;
0080:            }
0081:
0082:            public abstract boolean isLocked() throws SVNException;
0083:
0084:            public abstract boolean isVersioned();
0085:
0086:            protected abstract boolean isEntryPropertyApplicable(String name);
0087:
0088:            public abstract boolean lock(boolean stealLock) throws SVNException;
0089:
0090:            public abstract boolean unlock() throws SVNException;
0091:
0092:            public abstract SVNVersionedProperties getBaseProperties(String name)
0093:                    throws SVNException;
0094:
0095:            public abstract SVNVersionedProperties getRevertProperties(
0096:                    String name) throws SVNException;
0097:
0098:            public abstract SVNVersionedProperties getWCProperties(String name)
0099:                    throws SVNException;
0100:
0101:            public abstract SVNVersionedProperties getProperties(String name)
0102:                    throws SVNException;
0103:
0104:            public abstract void saveVersionedProperties(SVNLog log,
0105:                    boolean close) throws SVNException;
0106:
0107:            public abstract void saveWCProperties(boolean close)
0108:                    throws SVNException;
0109:
0110:            public abstract void saveEntries(boolean close) throws SVNException;
0111:
0112:            public abstract String getThisDirName();
0113:
0114:            public abstract boolean hasPropModifications(String entryName)
0115:                    throws SVNException;
0116:
0117:            public abstract boolean hasProperties(String entryName)
0118:                    throws SVNException;
0119:
0120:            public abstract SVNAdminArea createVersionedDirectory(File dir,
0121:                    String url, String rootURL, String uuid, long revNumber,
0122:                    boolean createMyself) throws SVNException;
0123:
0124:            public abstract SVNAdminArea upgradeFormat(SVNAdminArea adminArea)
0125:                    throws SVNException;
0126:
0127:            public abstract void postUpgradeFormat(int format)
0128:                    throws SVNException;
0129:
0130:            public abstract void postCommit(String fileName,
0131:                    long revisionNumber, boolean implicit,
0132:                    SVNErrorCode errorCode) throws SVNException;
0133:
0134:            public void updateURL(String rootURL, boolean recursive)
0135:                    throws SVNException {
0136:                SVNWCAccess wcAccess = getWCAccess();
0137:                for (Iterator ents = entries(false); ents.hasNext();) {
0138:                    SVNEntry entry = (SVNEntry) ents.next();
0139:                    if (!getThisDirName().equals(entry.getName())
0140:                            && entry.isDirectory() && recursive) {
0141:                        SVNAdminArea childDir = wcAccess.retrieve(getFile(entry
0142:                                .getName()));
0143:                        if (childDir != null) {
0144:                            String childURL = SVNPathUtil.append(rootURL,
0145:                                    SVNEncodingUtil.uriEncode(entry.getName()));
0146:                            childDir.updateURL(childURL, recursive);
0147:                        }
0148:                        continue;
0149:                    }
0150:                    entry
0151:                            .setURL(getThisDirName().equals(entry.getName()) ? rootURL
0152:                                    : SVNPathUtil.append(rootURL,
0153:                                            SVNEncodingUtil.uriEncode(entry
0154:                                                    .getName())));
0155:                }
0156:                saveEntries(false);
0157:            }
0158:
0159:            public boolean hasTextModifications(String name,
0160:                    boolean forceComparision) throws SVNException {
0161:                return hasTextModifications(name, forceComparision, true, false);
0162:            }
0163:
0164:            public boolean hasTextModifications(String name,
0165:                    boolean forceComparison, boolean compareTextBase,
0166:                    boolean compareChecksum) throws SVNException {
0167:                SVNEntry entry = getEntry(name, false);
0168:                SVNFileType fType = SVNFileType.getType(getFile(name));
0169:                if (!forceComparison && fType != SVNFileType.SYMLINK) {
0170:                    if (entry == null || entry.isDirectory()) {
0171:                        return false;
0172:                    }
0173:
0174:                    String textTime = entry.getTextTime();
0175:                    if (textTime != null) {
0176:                        long textTimeAsLong = SVNFileUtil
0177:                                .roundTimeStamp(SVNTimeUtil
0178:                                        .parseDateAsLong(textTime));
0179:                        long tstamp = SVNFileUtil.roundTimeStamp(getFile(name)
0180:                                .lastModified());
0181:                        if (textTimeAsLong == tstamp) {
0182:                            return false;
0183:                        }
0184:                    }
0185:                }
0186:                if (fType != SVNFileType.FILE && fType != SVNFileType.SYMLINK) {
0187:                    return false;
0188:                }
0189:                File textFile = getFile(name);
0190:                File baseFile = getBaseFile(name, false);
0191:                if (!baseFile.isFile()) {
0192:                    return true;
0193:                }
0194:                boolean differs = compareAndVerify(textFile, baseFile,
0195:                        compareTextBase, compareChecksum);
0196:                if (!differs && isLocked()) {
0197:                    entry.setTextTime(SVNTimeUtil.formatDate(new Date(textFile
0198:                            .lastModified())));
0199:                    saveEntries(false);
0200:                }
0201:                return differs;
0202:            }
0203:
0204:            private boolean compareAndVerify(File text, File baseFile,
0205:                    boolean compareTextBase, boolean checksum)
0206:                    throws SVNException {
0207:                String eolStyle = getProperties(text.getName())
0208:                        .getPropertyValue(SVNProperty.EOL_STYLE);
0209:                String keywords = getProperties(text.getName())
0210:                        .getPropertyValue(SVNProperty.KEYWORDS);
0211:                boolean special = getProperties(text.getName())
0212:                        .getPropertyValue(SVNProperty.SPECIAL) != null;
0213:
0214:                if (special) {
0215:                    compareTextBase = true;
0216:                }
0217:
0218:                boolean needsTranslation = eolStyle != null || keywords != null
0219:                        || special;
0220:                SVNChecksumInputStream checksumStream = null;
0221:                SVNEntry entry = null;
0222:
0223:                if (checksum || needsTranslation) {
0224:                    InputStream baseStream = null;
0225:                    InputStream textStream = null;
0226:                    entry = getEntry(text.getName(), true);
0227:                    if (entry == null) {
0228:                        SVNErrorMessage err = SVNErrorMessage.create(
0229:                                SVNErrorCode.UNVERSIONED_RESOURCE,
0230:                                "''{0}'' is not under version control", text);
0231:                        SVNErrorManager.error(err);
0232:                    }
0233:                    File tmpFile = null;
0234:                    try {
0235:                        baseStream = SVNFileUtil.openFileForReading(baseFile);
0236:                        textStream = special ? null : SVNFileUtil
0237:                                .openFileForReading(text);
0238:                        if (checksum) {
0239:                            if (entry.getChecksum() != null) {
0240:                                checksumStream = new SVNChecksumInputStream(
0241:                                        baseStream);
0242:                                baseStream = checksumStream;
0243:                            }
0244:                        }
0245:                        if (compareTextBase && needsTranslation) {
0246:                            if (!special) {
0247:                                Map keywordsMap = SVNTranslator
0248:                                        .computeKeywords(keywords, null, entry
0249:                                                .getAuthor(), entry
0250:                                                .getCommittedDate(), entry
0251:                                                .getRevision()
0252:                                                + "", getWCAccess()
0253:                                                .getOptions());
0254:                                byte[] eols = SVNTranslator
0255:                                        .getBaseEOL(eolStyle);
0256:                                textStream = new SVNTranslatorInputStream(
0257:                                        textStream, eols, false, keywordsMap,
0258:                                        false);
0259:                            } else {
0260:                                tmpFile = SVNFileUtil.createUniqueFile(
0261:                                        getAdminFile("tmp/text-base"), text
0262:                                                .getName(), ".tmp");
0263:                                String tmpPath = SVNFileUtil
0264:                                        .getBasePath(tmpFile);
0265:                                SVNTranslator.translate(this , text.getName(),
0266:                                        text.getName(), tmpPath, false);
0267:                                textStream = SVNFileUtil
0268:                                        .openFileForReading(getFile(tmpPath));
0269:                            }
0270:                        } else if (needsTranslation) {
0271:                            Map keywordsMap = SVNTranslator.computeKeywords(
0272:                                    keywords, entry.getURL(),
0273:                                    entry.getAuthor(),
0274:                                    entry.getCommittedDate(), entry
0275:                                            .getRevision()
0276:                                            + "", getWCAccess().getOptions());
0277:                            byte[] eols = SVNTranslator.getWorkingEOL(eolStyle);
0278:                            baseStream = new SVNTranslatorInputStream(
0279:                                    baseStream, eols, false, keywordsMap, true);
0280:                        }
0281:                        byte[] buffer1 = new byte[8192];
0282:                        byte[] buffer2 = new byte[8192];
0283:                        try {
0284:                            while (true) {
0285:                                int r1 = baseStream.read(buffer1);
0286:                                int r2 = textStream.read(buffer2);
0287:                                r1 = r1 == -1 ? 0 : r1;
0288:                                r2 = r2 == -1 ? 0 : r2;
0289:                                if (r1 != r2) {
0290:                                    return true;
0291:                                } else if (r1 == 0) {
0292:                                    return false;
0293:                                }
0294:                                for (int i = 0; i < r1; i++) {
0295:                                    if (buffer1[i] != buffer2[i]) {
0296:                                        return true;
0297:                                    }
0298:                                }
0299:                            }
0300:                        } catch (IOException e) {
0301:                            SVNErrorMessage err = SVNErrorMessage.create(
0302:                                    SVNErrorCode.IO_ERROR, e.getMessage());
0303:                            SVNErrorManager.error(err);
0304:                        }
0305:                    } finally {
0306:                        SVNFileUtil.closeFile(baseStream);
0307:                        SVNFileUtil.closeFile(textStream);
0308:                        SVNFileUtil.deleteFile(tmpFile);
0309:                    }
0310:                } else {
0311:                    return !SVNFileUtil.compareFiles(text, baseFile, null);
0312:                }
0313:                if (entry != null && checksumStream != null) {
0314:                    if (!entry.getChecksum().equals(checksumStream.getDigest())) {
0315:                        SVNErrorMessage err = SVNErrorMessage.create(
0316:                                SVNErrorCode.WC_CORRUPT_TEXT_BASE,
0317:                                "Checksum mismatch indicates corrupt text base: ''{0}''\n"
0318:                                        + "   expected: {1}\n"
0319:                                        + "     actual: {2}\n", new Object[] {
0320:                                        baseFile, entry.getChecksum(),
0321:                                        checksumStream.getDigest() });
0322:                        SVNErrorManager.error(err);
0323:                    }
0324:                }
0325:                return false;
0326:            }
0327:
0328:            public String getRelativePath(SVNAdminArea anchor) {
0329:                String absoluteAnchor = anchor.getRoot().getAbsolutePath();
0330:                String ownAbsolutePath = getRoot().getAbsolutePath();
0331:                String relativePath = ownAbsolutePath.substring(absoluteAnchor
0332:                        .length());
0333:
0334:                relativePath = relativePath.replace(File.separatorChar, '/');
0335:                if (relativePath.startsWith("/")) {
0336:                    relativePath = relativePath.substring(1);
0337:                }
0338:                if (relativePath.endsWith("/")) {
0339:                    relativePath = relativePath.substring(0, relativePath
0340:                            .length() - 1);
0341:                }
0342:                return relativePath;
0343:            }
0344:
0345:            public boolean tweakEntry(String name, String newURL,
0346:                    String reposRoot, long newRevision, boolean remove)
0347:                    throws SVNException {
0348:                boolean rewrite = false;
0349:                SVNEntry entry = getEntry(name, true);
0350:                if (entry == null) {
0351:                    SVNErrorMessage err = SVNErrorMessage.create(
0352:                            SVNErrorCode.ENTRY_NOT_FOUND,
0353:                            "No such entry: ''{0}''", name);
0354:                    SVNErrorManager.error(err);
0355:                }
0356:
0357:                if (newURL != null
0358:                        && (entry.getURL() == null || !newURL.equals(entry
0359:                                .getURL()))) {
0360:                    rewrite = true;
0361:                    entry.setURL(newURL);
0362:                }
0363:
0364:                if (reposRoot != null
0365:                        && (entry.getRepositoryRootURL() == null || !reposRoot
0366:                                .equals(entry.getRepositoryRoot()))
0367:                        && entry.getURL() != null
0368:                        && SVNPathUtil.isAncestor(reposRoot, entry.getURL())) {
0369:                    boolean setReposRoot = true;
0370:                    if (getThisDirName().equals(entry.getName())) {
0371:                        for (Iterator entries = entries(true); entries
0372:                                .hasNext();) {
0373:                            SVNEntry childEntry = (SVNEntry) entries.next();
0374:                            if (childEntry.getRepositoryRoot() == null
0375:                                    && childEntry.getURL() != null
0376:                                    && !SVNPathUtil.isAncestor(reposRoot, entry
0377:                                            .getURL())) {
0378:                                setReposRoot = false;
0379:                                break;
0380:                            }
0381:                        }
0382:                    }
0383:                    if (setReposRoot) {
0384:                        rewrite = true;
0385:                        entry.setRepositoryRoot(reposRoot);
0386:                    }
0387:                }
0388:
0389:                if (newRevision >= 0 && !entry.isScheduledForAddition()
0390:                        && !entry.isScheduledForReplacement()
0391:                        && entry.getRevision() != newRevision) {
0392:                    rewrite = true;
0393:                    entry.setRevision(newRevision);
0394:                }
0395:
0396:                if (remove
0397:                        && (entry.isDeleted() || (entry.isAbsent() && entry
0398:                                .getRevision() != newRevision))) {
0399:                    deleteEntry(name);
0400:                    rewrite = true;
0401:                }
0402:                return rewrite;
0403:            }
0404:
0405:            public boolean isKillMe() {
0406:                return getAdminFile("KILLME").isFile();
0407:            }
0408:
0409:            public boolean markResolved(String name, boolean text, boolean props)
0410:                    throws SVNException {
0411:                if (!text && !props) {
0412:                    return false;
0413:                }
0414:                SVNEntry entry = getEntry(name, true);
0415:                if (entry == null) {
0416:                    return false;
0417:                }
0418:                boolean filesDeleted = false;
0419:                boolean updateEntry = false;
0420:                if (text && entry.getConflictOld() != null) {
0421:                    File file = getFile(entry.getConflictOld());
0422:                    filesDeleted |= file.isFile();
0423:                    updateEntry = true;
0424:                    SVNFileUtil.deleteFile(file);
0425:                }
0426:                if (text && entry.getConflictNew() != null) {
0427:                    File file = getFile(entry.getConflictNew());
0428:                    filesDeleted |= file.isFile();
0429:                    updateEntry = true;
0430:                    SVNFileUtil.deleteFile(file);
0431:                }
0432:                if (text && entry.getConflictWorking() != null) {
0433:                    File file = getFile(entry.getConflictWorking());
0434:                    filesDeleted |= file.isFile();
0435:                    updateEntry = true;
0436:                    SVNFileUtil.deleteFile(file);
0437:                }
0438:                if (props && entry.getPropRejectFile() != null) {
0439:                    File file = getFile(entry.getPropRejectFile());
0440:                    filesDeleted |= file.isFile();
0441:                    updateEntry = true;
0442:                    SVNFileUtil.deleteFile(file);
0443:                }
0444:                if (updateEntry) {
0445:                    if (text) {
0446:                        entry.setConflictOld(null);
0447:                        entry.setConflictNew(null);
0448:                        entry.setConflictWorking(null);
0449:                    }
0450:                    if (props) {
0451:                        entry.setPropRejectFile(null);
0452:                    }
0453:                    saveEntries(false);
0454:                }
0455:                return filesDeleted;
0456:            }
0457:
0458:            public void restoreFile(String name) throws SVNException {
0459:                SVNVersionedProperties props = getProperties(name);
0460:                SVNEntry entry = getEntry(name, true);
0461:                boolean special = props.getPropertyValue(SVNProperty.SPECIAL) != null;
0462:
0463:                File src = getBaseFile(name, false);
0464:                File dst = getFile(name);
0465:                SVNTranslator.translate(this , name, SVNFileUtil
0466:                        .getBasePath(src), SVNFileUtil.getBasePath(dst), true);
0467:
0468:                boolean executable = props
0469:                        .getPropertyValue(SVNProperty.EXECUTABLE) != null;
0470:                boolean needsLock = props
0471:                        .getPropertyValue(SVNProperty.NEEDS_LOCK) != null;
0472:                if (needsLock) {
0473:                    SVNFileUtil.setReadonly(dst, entry.getLockToken() == null);
0474:                }
0475:                if (executable) {
0476:                    SVNFileUtil.setExecutable(dst, true);
0477:                }
0478:
0479:                markResolved(name, true, false);
0480:
0481:                long tstamp;
0482:                if (myWCAccess.getOptions().isUseCommitTimes() && !special) {
0483:                    entry.setTextTime(entry.getCommittedDate());
0484:                    tstamp = SVNTimeUtil.parseDate(entry.getCommittedDate())
0485:                            .getTime();
0486:                    dst.setLastModified(tstamp);
0487:                } else {
0488:                    tstamp = System.currentTimeMillis();
0489:                    dst.setLastModified(tstamp);
0490:                    entry.setTextTime(SVNTimeUtil.formatDate(new Date(tstamp)));
0491:                }
0492:                saveEntries(false);
0493:            }
0494:
0495:            public SVNStatusType mergeProperties(String name,
0496:                    Map serverBaseProps, Map propDiff, boolean baseMerge,
0497:                    boolean dryRun, SVNLog log) throws SVNException {
0498:                serverBaseProps = serverBaseProps == null ? Collections.EMPTY_MAP
0499:                        : serverBaseProps;
0500:                propDiff = propDiff == null ? Collections.EMPTY_MAP : propDiff;
0501:
0502:                SVNVersionedProperties working = getProperties(name);
0503:                Map workingProps = working.asMap();
0504:                SVNVersionedProperties base = getBaseProperties(name);
0505:
0506:                Collection conflicts = new ArrayList();
0507:                SVNStatusType result = propDiff.isEmpty() ? SVNStatusType.UNCHANGED
0508:                        : SVNStatusType.CHANGED;
0509:
0510:                for (Iterator propEntries = propDiff.entrySet().iterator(); propEntries
0511:                        .hasNext();) {
0512:                    Map.Entry incomingEntry = (Map.Entry) propEntries.next();
0513:                    String propName = (String) incomingEntry.getKey();
0514:                    String toValue = (String) incomingEntry.getValue();
0515:                    String fromValue = (String) serverBaseProps.get(propName);
0516:                    String workingValue = (String) workingProps.get(propName);
0517:                    boolean isNormal = SVNProperty.isRegularProperty(propName);
0518:                    if (baseMerge) {
0519:                        base.setPropertyValue(propName, toValue);
0520:                    }
0521:
0522:                    result = isNormal ? SVNStatusType.CHANGED : result;
0523:                    if (fromValue == null) {
0524:                        if (workingValue != null) {
0525:                            if (workingValue.equals(toValue)) {
0526:                                result = result != SVNStatusType.CONFLICTED
0527:                                        && isNormal ? SVNStatusType.MERGED
0528:                                        : result;
0529:                            } else {
0530:                                result = isNormal ? SVNStatusType.CONFLICTED
0531:                                        : result;
0532:                                conflicts
0533:                                        .add(MessageFormat
0534:                                                .format(
0535:                                                        "Trying to add new property ''{0}'' with value ''{1}'',\n"
0536:                                                                + "but property already exists with value ''{2}''.",
0537:                                                        new Object[] {
0538:                                                                propName,
0539:                                                                toValue,
0540:                                                                workingValue }));
0541:                            }
0542:                        } else {
0543:                            working.setPropertyValue(propName, toValue);
0544:                        }
0545:                    } else {
0546:                        if (workingValue == null) {
0547:                            if (toValue != null) {
0548:                                result = isNormal ? SVNStatusType.CONFLICTED
0549:                                        : result;
0550:                                conflicts
0551:                                        .add(MessageFormat
0552:                                                .format(
0553:                                                        "Trying to change property ''{0}'' from ''{1}'' to ''{2}'',\n"
0554:                                                                + "but the property does not exist.",
0555:                                                        new Object[] {
0556:                                                                propName,
0557:                                                                fromValue,
0558:                                                                toValue }));
0559:                            } else {
0560:                                result = result != SVNStatusType.CONFLICTED
0561:                                        && isNormal ? SVNStatusType.MERGED
0562:                                        : result;
0563:                            }
0564:                        } else {
0565:                            if (workingValue.equals(fromValue)) {
0566:                                working.setPropertyValue(propName, toValue);
0567:                            } else if (toValue == null
0568:                                    && !workingValue.equals(fromValue)) {
0569:                                result = isNormal ? SVNStatusType.CONFLICTED
0570:                                        : result;
0571:                                conflicts
0572:                                        .add(MessageFormat
0573:                                                .format(
0574:                                                        "Trying to delete property ''{0}'' but value has been modified from ''{1}'' to ''{2}''.",
0575:                                                        new Object[] {
0576:                                                                propName,
0577:                                                                fromValue,
0578:                                                                workingValue }));
0579:                            } else if (workingValue.equals(toValue)) {
0580:                                result = result != SVNStatusType.CONFLICTED
0581:                                        && isNormal ? SVNStatusType.MERGED
0582:                                        : result;
0583:                            } else {
0584:                                result = isNormal ? SVNStatusType.CONFLICTED
0585:                                        : result;
0586:
0587:                                conflicts
0588:                                        .add(MessageFormat
0589:                                                .format(
0590:                                                        "Trying to change property ''{0}'' from ''{1}'' to ''{2}'',\n"
0591:                                                                + "but property already exists with value ''{3}''.",
0592:                                                        new Object[] {
0593:                                                                propName,
0594:                                                                fromValue,
0595:                                                                toValue,
0596:                                                                workingValue }));
0597:                            }
0598:                        }
0599:                    }
0600:                }
0601:
0602:                Map command = new HashMap();
0603:                if (dryRun) {
0604:                    return result;
0605:                }
0606:                log = log == null ? getLog() : log;
0607:                saveVersionedProperties(log, true);
0608:
0609:                if (!conflicts.isEmpty()) {
0610:                    String prejTmpPath = getThisDirName().equals(name) ? "tmp/dir_conflicts"
0611:                            : "tmp/props/" + name;
0612:                    File prejTmpFile = SVNFileUtil.createUniqueFile(
0613:                            getAdminDirectory(), prejTmpPath, ".prej");
0614:
0615:                    prejTmpPath = SVNFileUtil.getBasePath(prejTmpFile);
0616:
0617:                    SVNEntry entry = getEntry(name, false);
0618:                    if (entry == null) {
0619:                        SVNErrorMessage err = SVNErrorMessage.create(
0620:                                SVNErrorCode.ENTRY_NOT_FOUND,
0621:                                "Can''t find entry ''{0}'' in ''{1}''",
0622:                                new Object[] { name, getRoot() });
0623:                        SVNErrorManager.error(err);
0624:                    }
0625:                    String prejPath = entry.getPropRejectFile();
0626:                    closeEntries();
0627:
0628:                    if (prejPath == null) {
0629:                        prejPath = getThisDirName().equals(name) ? "dir_conflicts"
0630:                                : name;
0631:                        File prejFile = SVNFileUtil.createUniqueFile(getRoot(),
0632:                                prejPath, ".prej");
0633:                        prejPath = SVNFileUtil.getBasePath(prejFile);
0634:                    }
0635:                    File file = getFile(prejTmpPath);
0636:
0637:                    OutputStream os = SVNFileUtil.openFileForWriting(file);
0638:                    try {
0639:                        for (Iterator lines = conflicts.iterator(); lines
0640:                                .hasNext();) {
0641:                            String line = (String) lines.next();
0642:                            os.write(SVNEncodingUtil.fuzzyEscape(line)
0643:                                    .getBytes("UTF-8"));
0644:                            //                    os.write(line.getBytes("UTF-8"));
0645:                        }
0646:                    } catch (IOException e) {
0647:                        SVNErrorMessage err = SVNErrorMessage.create(
0648:                                SVNErrorCode.IO_ERROR,
0649:                                "Cannot write properties conflict file: {1}", e
0650:                                        .getLocalizedMessage());
0651:                        SVNErrorManager.error(err, e);
0652:                    } finally {
0653:                        SVNFileUtil.closeFile(os);
0654:                    }
0655:
0656:                    command.put(SVNLog.NAME_ATTR, prejTmpPath);
0657:                    command.put(SVNLog.DEST_ATTR, prejPath);
0658:                    log.addCommand(SVNLog.APPEND, command, false);
0659:                    command.clear();
0660:
0661:                    command.put(SVNLog.NAME_ATTR, prejTmpPath);
0662:                    log.addCommand(SVNLog.DELETE, command, false);
0663:                    command.clear();
0664:
0665:                    command.put(SVNLog.NAME_ATTR, name);
0666:                    command.put(SVNProperty
0667:                            .shortPropertyName(SVNProperty.PROP_REJECT_FILE),
0668:                            prejPath);
0669:                    log.addCommand(SVNLog.MODIFY_ENTRY, command, false);
0670:                }
0671:                return result;
0672:            }
0673:
0674:            public SVNStatusType mergeText(String localPath, File base,
0675:                    File latest, String localLabel, String baseLabel,
0676:                    String latestLabel, boolean leaveConflict, boolean dryRun)
0677:                    throws SVNException {
0678:                return mergeText(localPath, base, latest, localLabel,
0679:                        baseLabel, latestLabel, leaveConflict, dryRun, null);
0680:            }
0681:
0682:            public SVNStatusType mergeText(String localPath, File base,
0683:                    File latest, String localLabel, String baseLabel,
0684:                    String latestLabel, boolean leaveConflict, boolean dryRun,
0685:                    SVNDiffOptions options) throws SVNException {
0686:                SVNEntry entry = getEntry(localPath, false);
0687:                if (entry == null) {
0688:                    return SVNStatusType.UNCHANGED;
0689:                }
0690:
0691:                SVNVersionedProperties props = getProperties(localPath);
0692:                String mimeType = props.getPropertyValue(SVNProperty.MIME_TYPE);
0693:                SVNStatusType status = SVNStatusType.UNCHANGED;
0694:
0695:                byte[] conflictStart = ("<<<<<<< " + localLabel).getBytes();
0696:                byte[] conflictEnd = (">>>>>>> " + latestLabel).getBytes();
0697:                byte[] separator = ("=======").getBytes();
0698:                ISVNMergerFactory factory = myWCAccess.getOptions()
0699:                        .getMergerFactory();
0700:                ISVNMerger merger = factory.createMerger(conflictStart,
0701:                        separator, conflictEnd);
0702:                boolean customMerger = merger.getClass() != DefaultSVNMerger.class;
0703:
0704:                if (SVNProperty.isBinaryMimeType(mimeType) && !customMerger) {
0705:                    // binary
0706:                    if (!dryRun) {
0707:                        File oldFile = SVNFileUtil.createUniqueFile(getRoot(),
0708:                                localPath, baseLabel);
0709:                        File newFile = SVNFileUtil.createUniqueFile(getRoot(),
0710:                                localPath, latestLabel);
0711:                        SVNFileUtil.copyFile(base, oldFile, false);
0712:                        SVNFileUtil.copyFile(latest, newFile, false);
0713:                        // update entry props
0714:                        entry.setConflictNew(SVNFileUtil.getBasePath(newFile));
0715:                        entry.setConflictOld(SVNFileUtil.getBasePath(oldFile));
0716:                        entry.setConflictWorking(null);
0717:                        saveEntries(false);
0718:                    }
0719:                    status = SVNStatusType.CONFLICTED;
0720:                } else {
0721:                    // text
0722:                    // 1. destranslate local
0723:                    File localTmpFile = SVNFileUtil.createUniqueFile(getRoot(),
0724:                            localPath, ".tmp");
0725:                    SVNTranslator.translate(this , localPath, localPath,
0726:                            SVNFileUtil.getBasePath(localTmpFile), false);
0727:                    // 2. run merge between all files we have :)
0728:                    OutputStream result = null;
0729:                    File resultFile = dryRun ? null : SVNFileUtil
0730:                            .createUniqueFile(getRoot(), localPath, ".result");
0731:
0732:                    result = resultFile == null ? SVNFileUtil.DUMMY_OUT
0733:                            : SVNFileUtil.openFileForWriting(resultFile);
0734:                    try {
0735:                        status = SVNProperty.isBinaryMimeType(mimeType) ? merger
0736:                                .mergeBinary(base, localTmpFile, latest,
0737:                                        dryRun, result)
0738:                                : merger.mergeText(base, localTmpFile, latest,
0739:                                        dryRun, options, result);
0740:                    } finally {
0741:                        SVNFileUtil.closeFile(result);
0742:                    }
0743:                    if (dryRun) {
0744:                        localTmpFile.delete();
0745:                        if (leaveConflict && status == SVNStatusType.CONFLICTED) {
0746:                            status = SVNStatusType.CONFLICTED_UNRESOLVED;
0747:                        }
0748:                    } else {
0749:                        if (status != SVNStatusType.CONFLICTED) {
0750:                            SVNTranslator.translate(this , localPath,
0751:                                    SVNFileUtil.getBasePath(resultFile),
0752:                                    localPath, true);
0753:                        } else {
0754:                            // copy all to wc.
0755:                            File mineFile = SVNFileUtil.createUniqueFile(
0756:                                    getRoot(), localPath, localLabel);
0757:                            String minePath = SVNFileUtil.getBasePath(mineFile);
0758:                            SVNFileUtil.copyFile(getFile(localPath), mineFile,
0759:                                    false);
0760:                            File oldFile = SVNFileUtil.createUniqueFile(
0761:                                    getRoot(), localPath, baseLabel);
0762:                            String oldPath = SVNFileUtil.getBasePath(oldFile);
0763:                            File newFile = SVNFileUtil.createUniqueFile(
0764:                                    getRoot(), localPath, latestLabel);
0765:                            String newPath = SVNFileUtil.getBasePath(newFile);
0766:
0767:                            SVNTranslator.translate(this , localPath, base,
0768:                                    oldFile, true);
0769:                            SVNTranslator.translate(this , localPath, latest,
0770:                                    newFile, true);
0771:                            // translate result to local
0772:                            if (!leaveConflict) {
0773:                                SVNTranslator.translate(this , localPath,
0774:                                        SVNFileUtil.getBasePath(resultFile),
0775:                                        localPath, true);
0776:                            }
0777:
0778:                            entry.setConflictNew(newPath);
0779:                            entry.setConflictOld(oldPath);
0780:                            entry.setConflictWorking(minePath);
0781:                            saveEntries(false);
0782:                        }
0783:                    }
0784:                    localTmpFile.delete();
0785:                    if (resultFile != null) {
0786:                        resultFile.delete();
0787:                    }
0788:                    if (status == SVNStatusType.CONFLICTED && leaveConflict) {
0789:                        status = SVNStatusType.CONFLICTED_UNRESOLVED;
0790:                    }
0791:                }
0792:
0793:                if (!dryRun) {
0794:                    boolean executable = SVNFileUtil.isWindows ? false : props
0795:                            .getPropertyValue(SVNProperty.EXECUTABLE) != null;
0796:
0797:                    if (executable) {
0798:                        SVNFileUtil.setExecutable(getFile(localPath), true);
0799:                    }
0800:                    if (entry.getLockToken() == null
0801:                            && props.getPropertyValue(SVNProperty.NEEDS_LOCK) != null) {
0802:                        SVNFileUtil.setReadonly(getFile(localPath), true);
0803:                    }
0804:                }
0805:                return status;
0806:            }
0807:
0808:            public InputStream getBaseFileForReading(String name, boolean tmp)
0809:                    throws SVNException {
0810:                String path = tmp ? "tmp/" : "";
0811:                path += "text-base/" + name + ".svn-base";
0812:                File baseFile = getAdminFile(path);
0813:                return SVNFileUtil.openFileForReading(baseFile);
0814:            }
0815:
0816:            public OutputStream getBaseFileForWriting(String name)
0817:                    throws SVNException {
0818:                final String fileName = name;
0819:                final File tmpFile = getBaseFile(name, true);
0820:                try {
0821:                    final OutputStream os = SVNFileUtil
0822:                            .openFileForWriting(tmpFile);
0823:                    return new OutputStream() {
0824:                        private String myName = fileName;
0825:                        private File myTmpFile = tmpFile;
0826:
0827:                        public void write(int b) throws IOException {
0828:                            os.write(b);
0829:                        }
0830:
0831:                        public void write(byte[] b) throws IOException {
0832:                            os.write(b);
0833:                        }
0834:
0835:                        public void write(byte[] b, int off, int len)
0836:                                throws IOException {
0837:                            os.write(b, off, len);
0838:                        }
0839:
0840:                        public void close() throws IOException {
0841:                            os.close();
0842:                            File baseFile = getBaseFile(myName, false);
0843:                            try {
0844:                                SVNFileUtil.rename(myTmpFile, baseFile);
0845:                            } catch (SVNException e) {
0846:                                throw new IOException(e.getMessage());
0847:                            }
0848:                            SVNFileUtil.setReadonly(baseFile, true);
0849:                        }
0850:                    };
0851:                } catch (SVNException svne) {
0852:                    SVNErrorMessage err = svne
0853:                            .getErrorMessage()
0854:                            .wrap(
0855:                                    "Your .svn/tmp directory may be missing or corrupt; run 'svn cleanup' and try again");
0856:                    SVNErrorManager.error(err);
0857:                }
0858:                return null;
0859:            }
0860:
0861:            public String getPropertyTime(String name) {
0862:                String path = getThisDirName().equals(name) ? "dir-props"
0863:                        : "props/" + name + ".svn-work";
0864:                File file = getAdminFile(path);
0865:                return SVNTimeUtil.formatDate(new Date(file.lastModified()));
0866:            }
0867:
0868:            public SVNLog getLog() {
0869:                int index = 0;
0870:                File logFile = null;
0871:                File tmpFile = null;
0872:                while (true) {
0873:                    logFile = getAdminFile("log"
0874:                            + (index == 0 ? "" : "." + index));
0875:                    if (logFile.exists()) {
0876:                        index++;
0877:                        continue;
0878:                    }
0879:                    tmpFile = getAdminFile("tmp/log"
0880:                            + (index == 0 ? "" : "." + index));
0881:                    return new SVNLogImpl(logFile, tmpFile, this );
0882:                }
0883:            }
0884:
0885:            public void runLogs() throws SVNException {
0886:                SVNLogRunner runner = new SVNLogRunner();
0887:                int index = 0;
0888:                SVNLog log = null;
0889:                try {
0890:                    File logFile = null;
0891:                    while (true) {
0892:                        if (getWCAccess() != null) {
0893:                            getWCAccess().checkCancelled();
0894:                        }
0895:                        logFile = getAdminFile("log"
0896:                                + (index == 0 ? "" : "." + index));
0897:                        log = new SVNLogImpl(logFile, null, this );
0898:                        if (log.exists()) {
0899:                            log.run(runner);
0900:                            markLogProcessed(logFile);
0901:                            index++;
0902:                            continue;
0903:                        }
0904:                        break;
0905:                    }
0906:                } catch (Throwable e) {
0907:                    runner.logFailed(this );
0908:                    if (e instanceof  SVNException) {
0909:                        throw (SVNException) e;
0910:                    } else if (e instanceof  Error) {
0911:                        throw (Error) e;
0912:                    }
0913:                    throw new SVNException(SVNErrorMessage
0914:                            .create(SVNErrorCode.UNKNOWN), e);
0915:                }
0916:                runner.logCompleted(this );
0917:                // delete all logs, there shoudn't be left unprocessed.
0918:                File[] logsFiles = getAdminDirectory().listFiles();
0919:                if (logsFiles != null) {
0920:                    for (int i = 0; i < logsFiles.length; i++) {
0921:                        if (logsFiles[i].getName().startsWith("log")
0922:                                && logsFiles[i].isFile()) {
0923:                            SVNFileUtil.deleteFile(logsFiles[i]);
0924:                        }
0925:                    }
0926:                }
0927:            }
0928:
0929:            private static void markLogProcessed(File logFile)
0930:                    throws SVNException {
0931:                SVNFileUtil.deleteFile(logFile);
0932:                SVNFileUtil.createEmptyFile(logFile);
0933:            }
0934:
0935:            public void removeFromRevisionControl(String name,
0936:                    boolean deleteWorkingFiles, boolean reportInstantError)
0937:                    throws SVNException {
0938:                getWCAccess().checkCancelled();
0939:                boolean isFile = !getThisDirName().equals(name);
0940:                boolean leftSomething = false;
0941:
0942:                if (isFile) {
0943:                    File path = getFile(name);
0944:                    boolean textModified = false;
0945:                    boolean wasSpecial = false;
0946:                    boolean isSpecial = false;
0947:                    if (deleteWorkingFiles) {
0948:                        wasSpecial = getProperties(name).containsProperty(
0949:                                SVNProperty.SPECIAL);
0950:                        isSpecial = SVNFileType.getType(path) == SVNFileType.SYMLINK;
0951:                        if (!(!wasSpecial && isSpecial)) {
0952:                            textModified = hasTextModifications(name, false);
0953:                            if (reportInstantError && textModified) {
0954:                                SVNErrorMessage err = SVNErrorMessage.create(
0955:                                        SVNErrorCode.WC_LEFT_LOCAL_MOD,
0956:                                        "File ''{0}'' has local modifications",
0957:                                        path);
0958:                                SVNErrorManager.error(err);
0959:                            }
0960:                        }
0961:                    }
0962:                    SVNPropertiesManager.deleteWCProperties(this , name, false);
0963:                    deleteEntry(name);
0964:                    saveEntries(false);
0965:
0966:                    SVNFileUtil.deleteFile(getFile(SVNAdminUtil
0967:                            .getTextBasePath(name, false)));
0968:                    SVNFileUtil.deleteFile(getFile(SVNAdminUtil.getPropPath(
0969:                            name, isFile ? SVNNodeKind.FILE : SVNNodeKind.DIR,
0970:                            false)));
0971:                    SVNFileUtil.deleteFile(getFile(SVNAdminUtil
0972:                            .getPropBasePath(name, isFile ? SVNNodeKind.FILE
0973:                                    : SVNNodeKind.DIR, false)));
0974:                    if (deleteWorkingFiles) {
0975:                        if (textModified || (!wasSpecial && isSpecial)) {
0976:                            SVNErrorMessage err = SVNErrorMessage
0977:                                    .create(SVNErrorCode.WC_LEFT_LOCAL_MOD);
0978:                            SVNErrorManager.error(err);
0979:                        } else if (myCommitParameters == null
0980:                                || myCommitParameters.onFileDeletion(path)) {
0981:                            SVNFileUtil.deleteFile(path);
0982:                        }
0983:                    }
0984:                } else {
0985:                    SVNEntry dirEntry = getEntry(getThisDirName(), false);
0986:                    dirEntry.setIncomplete(true);
0987:                    saveEntries(false);
0988:                    SVNPropertiesManager.deleteWCProperties(this ,
0989:                            getThisDirName(), false);
0990:                    for (Iterator entries = entries(false); entries.hasNext();) {
0991:                        SVNEntry entry = (SVNEntry) entries.next();
0992:                        String entryName = getThisDirName().equals(
0993:                                entry.getName()) ? null : entry.getName();
0994:                        if (entry.isFile()) {
0995:                            try {
0996:                                removeFromRevisionControl(entryName,
0997:                                        deleteWorkingFiles, reportInstantError);
0998:                            } catch (SVNException e) {
0999:                                if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_LEFT_LOCAL_MOD) {
1000:                                    if (reportInstantError) {
1001:                                        throw e;
1002:                                    }
1003:                                    leftSomething = true;
1004:                                } else {
1005:                                    throw e;
1006:                                }
1007:                            }
1008:                        } else if (entryName != null && entry.isDirectory()) {
1009:                            File entryPath = getFile(entryName);
1010:                            if (getWCAccess().isMissing(entryPath)) {
1011:                                deleteEntry(entryName);
1012:                            } else {
1013:                                try {
1014:                                    SVNAdminArea entryArea = getWCAccess()
1015:                                            .retrieve(entryPath);
1016:                                    entryArea.removeFromRevisionControl(
1017:                                            getThisDirName(),
1018:                                            deleteWorkingFiles,
1019:                                            reportInstantError);
1020:                                } catch (SVNException e) {
1021:                                    if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_LEFT_LOCAL_MOD) {
1022:                                        if (reportInstantError) {
1023:                                            throw e;
1024:                                        }
1025:                                        leftSomething = true;
1026:                                    } else {
1027:                                        throw e;
1028:                                    }
1029:                                }
1030:                            }
1031:                        }
1032:                    }
1033:                    if (!getWCAccess().isWCRoot(getRoot())) {
1034:                        getWCAccess().retrieve(getRoot().getParentFile())
1035:                                .deleteEntry(getRoot().getName());
1036:                        getWCAccess().retrieve(getRoot().getParentFile())
1037:                                .saveEntries(false);
1038:                    }
1039:                    destroyAdminArea();
1040:                    if (deleteWorkingFiles && !leftSomething) {
1041:                        if ((myCommitParameters == null || myCommitParameters
1042:                                .onDirectoryDeletion(getRoot()))
1043:                                && !getRoot().delete()) {
1044:                            // shouldn't throw exception when directory was intentionally left non-empty.
1045:                            leftSomething = true;
1046:                        }
1047:                    }
1048:
1049:                }
1050:                // remove cached props from this
1051:                if (myBaseProperties != null) {
1052:                    myBaseProperties.remove(name);
1053:                }
1054:                if (myProperties != null) {
1055:                    myProperties.remove(name);
1056:                }
1057:                if (leftSomething && myCommitParameters == null) {
1058:                    SVNErrorMessage err = SVNErrorMessage
1059:                            .create(SVNErrorCode.WC_LEFT_LOCAL_MOD);
1060:                    SVNErrorManager.error(err);
1061:                }
1062:            }
1063:
1064:            public void foldScheduling(String name, Map attributes,
1065:                    boolean force) throws SVNException {
1066:                if (!attributes.containsKey(SVNProperty
1067:                        .shortPropertyName(SVNProperty.SCHEDULE))
1068:                        || force) {
1069:                    return;
1070:                }
1071:                String schedule = (String) attributes.get(SVNProperty
1072:                        .shortPropertyName(SVNProperty.SCHEDULE));
1073:                schedule = "".equals(schedule) ? null : schedule;
1074:
1075:                SVNEntry entry = getEntry(name, true);
1076:                if (entry == null) {
1077:                    if (SVNProperty.SCHEDULE_ADD.equals(schedule)) {
1078:                        return;
1079:                    }
1080:                    SVNErrorMessage err = SVNErrorMessage.create(
1081:                            SVNErrorCode.WC_SCHEDULE_CONFLICT,
1082:                            "''{0}'' is not under version control", name);
1083:                    SVNErrorManager.error(err);
1084:                }
1085:
1086:                SVNEntry this DirEntry = getEntry(getThisDirName(), true);
1087:                if (!getThisDirName().equals(entry.getName())
1088:                        && this DirEntry.isScheduledForDeletion()) {
1089:                    if (SVNProperty.SCHEDULE_ADD.equals(schedule)) {
1090:                        SVNErrorMessage err = SVNErrorMessage
1091:                                .create(
1092:                                        SVNErrorCode.WC_SCHEDULE_CONFLICT,
1093:                                        "Can''t add ''{0}'' to deleted directory; try undeleting its parent directory first",
1094:                                        name);
1095:                        SVNErrorManager.error(err);
1096:                    } else if (SVNProperty.SCHEDULE_REPLACE.equals(schedule)) {
1097:                        SVNErrorMessage err = SVNErrorMessage
1098:                                .create(
1099:                                        SVNErrorCode.WC_SCHEDULE_CONFLICT,
1100:                                        "Can''t replace ''{0}'' in deleted directory; try undeleting its parent directory first",
1101:                                        name);
1102:                        SVNErrorManager.error(err);
1103:                    }
1104:                }
1105:
1106:                if (entry.isAbsent()
1107:                        && SVNProperty.SCHEDULE_ADD.equals(schedule)) {
1108:                    SVNErrorMessage err = SVNErrorMessage
1109:                            .create(
1110:                                    SVNErrorCode.WC_SCHEDULE_CONFLICT,
1111:                                    "''{0}'' is marked as absent, so it cannot be scheduled for addition",
1112:                                    name);
1113:                    SVNErrorManager.error(err);
1114:                }
1115:
1116:                if (SVNProperty.SCHEDULE_ADD.equals(entry.getSchedule())) {
1117:                    if (SVNProperty.SCHEDULE_DELETE.equals(schedule)) {
1118:                        if (!entry.isDeleted()) {
1119:                            deleteEntry(name);
1120:                        } else {
1121:                            attributes.put(SVNProperty
1122:                                    .shortPropertyName(SVNProperty.SCHEDULE),
1123:                                    null);
1124:                        }
1125:                    } else {
1126:                        attributes.remove(SVNProperty
1127:                                .shortPropertyName(SVNProperty.SCHEDULE));
1128:                    }
1129:                } else if (SVNProperty.SCHEDULE_DELETE.equals(entry
1130:                        .getSchedule())) {
1131:                    if (SVNProperty.SCHEDULE_DELETE.equals(schedule)) {
1132:                        attributes.remove(SVNProperty
1133:                                .shortPropertyName(SVNProperty.SCHEDULE));
1134:                    } else if (SVNProperty.SCHEDULE_ADD.equals(schedule)) {
1135:                        attributes.put(SVNProperty
1136:                                .shortPropertyName(SVNProperty.SCHEDULE),
1137:                                SVNProperty.SCHEDULE_REPLACE);
1138:                    }
1139:                } else if (SVNProperty.SCHEDULE_REPLACE.equals(entry
1140:                        .getSchedule())) {
1141:                    if (SVNProperty.SCHEDULE_DELETE.equals(schedule)) {
1142:                        attributes.put(SVNProperty
1143:                                .shortPropertyName(SVNProperty.SCHEDULE),
1144:                                SVNProperty.SCHEDULE_DELETE);
1145:                    } else if (SVNProperty.SCHEDULE_ADD.equals(schedule)
1146:                            || SVNProperty.SCHEDULE_REPLACE.equals(schedule)) {
1147:                        attributes.remove(SVNProperty
1148:                                .shortPropertyName(SVNProperty.SCHEDULE));
1149:                    }
1150:                } else {
1151:                    if (SVNProperty.SCHEDULE_ADD.equals(schedule)
1152:                            && !entry.isDeleted()) {
1153:                        SVNErrorMessage err = SVNErrorMessage
1154:                                .create(
1155:                                        SVNErrorCode.WC_SCHEDULE_CONFLICT,
1156:                                        "Entry ''{0}'' is already under version control",
1157:                                        name);
1158:                        SVNErrorManager.error(err);
1159:                    } else if (schedule == null) {
1160:                        attributes.remove(SVNProperty
1161:                                .shortPropertyName(SVNProperty.SCHEDULE));
1162:                    }
1163:                }
1164:            }
1165:
1166:            public void modifyEntry(String name, Map attributes, boolean save,
1167:                    boolean force) throws SVNException {
1168:                if (name == null) {
1169:                    name = getThisDirName();
1170:                }
1171:
1172:                boolean deleted = false;
1173:                if (attributes.containsKey(SVNProperty
1174:                        .shortPropertyName(SVNProperty.SCHEDULE))) {
1175:                    SVNEntry entryBefore = getEntry(name, true);
1176:                    foldScheduling(name, attributes, force);
1177:                    SVNEntry entryAfter = getEntry(name, true);
1178:                    if (entryBefore != null && entryAfter == null) {
1179:                        deleted = true;
1180:                    }
1181:                }
1182:
1183:                if (!deleted) {
1184:                    SVNEntry entry = getEntry(name, true);
1185:                    if (entry == null) {
1186:                        entry = addEntry(name);
1187:                    }
1188:
1189:                    Map entryAttrs = entry.asMap();
1190:                    for (Iterator atts = attributes.keySet().iterator(); atts
1191:                            .hasNext();) {
1192:                        String attName = (String) atts.next();
1193:                        String value = (String) attributes.get(attName);
1194:                        if (SVNProperty.CACHABLE_PROPS.equals(attName)
1195:                                || SVNProperty.PRESENT_PROPS.equals(attName)) {
1196:                            String[] propsArray = SVNAdminArea.fromString(
1197:                                    value, " ");
1198:                            entryAttrs.put(attName, propsArray);
1199:                            continue;
1200:                        } else if (!(SVNProperty.HAS_PROPS.equals(attName) || SVNProperty.HAS_PROP_MODS
1201:                                .equals(attName))) {
1202:                            attName = SVNProperty.SVN_ENTRY_PREFIX + attName;
1203:                        }
1204:
1205:                        if (value != null) {
1206:                            entryAttrs.put(attName, value);
1207:                        } else {
1208:                            entryAttrs.remove(attName);
1209:                        }
1210:                    }
1211:
1212:                    if (!entry.isDirectory()) {
1213:                        SVNEntry rootEntry = getEntry(getThisDirName(), true);
1214:                        if (rootEntry != null) {
1215:                            if (!SVNRevision.isValidRevisionNumber(entry
1216:                                    .getRevision())) {
1217:                                entry.setRevision(rootEntry.getRevision());
1218:                            }
1219:                            if (entry.getURL() == null) {
1220:                                entry.setURL(SVNPathUtil.append(rootEntry
1221:                                        .getURL(), SVNEncodingUtil
1222:                                        .uriEncode(name)));
1223:                            }
1224:                            if (entry.getRepositoryRoot() == null) {
1225:                                entry.setRepositoryRoot(rootEntry
1226:                                        .getRepositoryRoot());
1227:                            }
1228:                            if (entry.getUUID() == null
1229:                                    && !entry.isScheduledForAddition()
1230:                                    && !entry.isScheduledForReplacement()) {
1231:                                entry.setUUID(rootEntry.getUUID());
1232:                            }
1233:                            if (isEntryPropertyApplicable(SVNProperty.CACHABLE_PROPS)) {
1234:                                if (entry.getCachableProperties() == null) {
1235:                                    entry.setCachableProperties(rootEntry
1236:                                            .getCachableProperties());
1237:                                }
1238:                            }
1239:                        }
1240:                    }
1241:
1242:                    if (attributes.containsKey(SVNProperty
1243:                            .shortPropertyName(SVNProperty.SCHEDULE))
1244:                            && entry.isScheduledForDeletion()) {
1245:                        entry.setCopied(false);
1246:                        entry.setCopyFromRevision(-1);
1247:                        entry.setCopyFromURL(null);
1248:                    }
1249:                }
1250:
1251:                if (save) {
1252:                    saveEntries(false);
1253:                }
1254:            }
1255:
1256:            public void deleteEntry(String name) throws SVNException {
1257:                Map entries = loadEntries();
1258:                if (entries != null) {
1259:                    entries.remove(name);
1260:                }
1261:            }
1262:
1263:            public SVNEntry getEntry(String name, boolean hidden)
1264:                    throws SVNException {
1265:                Map entries = loadEntries();
1266:                if (entries != null && entries.containsKey(name)) {
1267:                    SVNEntry entry = (SVNEntry) entries.get(name);
1268:                    if (!hidden && entry.isHidden()) {
1269:                        return null;
1270:                    }
1271:                    return entry;
1272:                }
1273:                return null;
1274:            }
1275:
1276:            public SVNEntry addEntry(String name) throws SVNException {
1277:                Map entries = loadEntries();
1278:                if (entries == null) {
1279:                    myEntries = new HashMap();
1280:                    entries = myEntries;
1281:                }
1282:
1283:                SVNEntry entry = entries.containsKey(name) ? (SVNEntry) entries
1284:                        .get(name) : new SVNEntry(new HashMap(), this , name);
1285:                entries.put(name, entry);
1286:                return entry;
1287:            }
1288:
1289:            public Iterator entries(boolean hidden) throws SVNException {
1290:                Map entries = loadEntries();
1291:                if (entries == null) {
1292:                    return Collections.EMPTY_LIST.iterator();
1293:                }
1294:                List copy = new ArrayList(entries.values());
1295:                if (!hidden) {
1296:                    for (Iterator iterator = copy.iterator(); iterator
1297:                            .hasNext();) {
1298:                        SVNEntry entry = (SVNEntry) iterator.next();
1299:                        if (entry.isHidden()) {
1300:                            iterator.remove();
1301:                        }
1302:                    }
1303:                }
1304:                Collections.sort(copy);
1305:                return copy.iterator();
1306:            }
1307:
1308:            public Map getEntries() throws SVNException {
1309:                return loadEntries();
1310:            }
1311:
1312:            public void cleanup() throws SVNException {
1313:                getWCAccess().checkCancelled();
1314:                for (Iterator entries = entries(false); entries.hasNext();) {
1315:                    SVNEntry entry = (SVNEntry) entries.next();
1316:                    if (entry.getKind() == SVNNodeKind.DIR
1317:                            && !getThisDirName().equals(entry.getName())) {
1318:                        File childDir = getFile(entry.getName());
1319:                        if (childDir.isDirectory()) {
1320:                            try {
1321:                                SVNAdminArea child = getWCAccess().open(
1322:                                        childDir, true, true, 0);
1323:                                child.cleanup();
1324:                            } catch (SVNException e) {
1325:                                if (e instanceof  SVNCancelException) {
1326:                                    throw e;
1327:                                }
1328:                                if (isSafeCleanup()) {
1329:                                    SVNDebugLog.getDefaultLog().info(
1330:                                            "CLEANUP FAILED for " + childDir);
1331:                                    SVNDebugLog.getDefaultLog().info(e);
1332:                                    continue;
1333:                                }
1334:                                throw e;
1335:                            }
1336:                        }
1337:                    } else {
1338:                        hasPropModifications(entry.getName());
1339:                        if (entry.getKind() == SVNNodeKind.FILE) {
1340:                            hasTextModifications(entry.getName(), false);
1341:                        }
1342:                    }
1343:                }
1344:                if (isKillMe()) {
1345:                    removeFromRevisionControl(getThisDirName(), true, false);
1346:                } else {
1347:                    runLogs();
1348:                }
1349:                SVNFileUtil.deleteAll(getAdminFile("tmp"), false);
1350:            }
1351:
1352:            public boolean hasTextConflict(String name) throws SVNException {
1353:                SVNEntry entry = getEntry(name, false);
1354:                if (entry == null || entry.getKind() != SVNNodeKind.FILE) {
1355:                    return false;
1356:                }
1357:                boolean conflicted = false;
1358:                if (entry.getConflictNew() != null) {
1359:                    conflicted = SVNFileType.getType(getFile(entry
1360:                            .getConflictNew())) == SVNFileType.FILE;
1361:                }
1362:                if (!conflicted && entry.getConflictWorking() != null) {
1363:                    conflicted = SVNFileType.getType(getFile(entry
1364:                            .getConflictWorking())) == SVNFileType.FILE;
1365:                }
1366:                if (!conflicted && entry.getConflictOld() != null) {
1367:                    conflicted = SVNFileType.getType(getFile(entry
1368:                            .getConflictOld())) == SVNFileType.FILE;
1369:                }
1370:                return conflicted;
1371:            }
1372:
1373:            public boolean hasPropConflict(String name) throws SVNException {
1374:                SVNEntry entry = getEntry(name, false);
1375:                if (entry != null && entry.getPropRejectFile() != null) {
1376:                    return SVNFileType.getType(getFile(entry
1377:                            .getPropRejectFile())) == SVNFileType.FILE;
1378:                }
1379:                return false;
1380:            }
1381:
1382:            public File getRoot() {
1383:                return myDirectory;
1384:            }
1385:
1386:            public File getAdminDirectory() {
1387:                return myAdminRoot;
1388:            }
1389:
1390:            public File getAdminFile(String name) {
1391:                return new File(getAdminDirectory(), name);
1392:            }
1393:
1394:            public File getFile(String name) {
1395:                if (name == null) {
1396:                    return null;
1397:                }
1398:                return new File(getRoot(), name);
1399:            }
1400:
1401:            public SVNWCAccess getWCAccess() {
1402:                return myWCAccess;
1403:            }
1404:
1405:            public void setWCAccess(SVNWCAccess wcAccess) {
1406:                myWCAccess = wcAccess;
1407:            }
1408:
1409:            public void closeVersionedProperties() {
1410:                myProperties = null;
1411:                myBaseProperties = null;
1412:            }
1413:
1414:            public void closeWCProperties() {
1415:                myWCProperties = null;
1416:            }
1417:
1418:            public void closeEntries() {
1419:                myEntries = null;
1420:            }
1421:
1422:            public File getBaseFile(String name, boolean tmp) {
1423:                String path = tmp ? "tmp/" : "";
1424:                path += "text-base/" + name + ".svn-base";
1425:                return getAdminFile(path);
1426:            }
1427:
1428:            protected abstract void writeEntries(Writer writer)
1429:                    throws IOException;
1430:
1431:            protected abstract int getFormatVersion();
1432:
1433:            protected abstract Map fetchEntries() throws SVNException;
1434:
1435:            protected SVNAdminArea(File dir) {
1436:                myDirectory = dir;
1437:                myAdminRoot = new File(dir, SVNFileUtil.getAdminDirectoryName());
1438:            }
1439:
1440:            protected File getBasePropertiesFile(String name, boolean tmp) {
1441:                String path = !tmp ? "" : "tmp/";
1442:                path += getThisDirName().equals(name) ? "dir-prop-base"
1443:                        : "prop-base/" + name + ".svn-base";
1444:                File propertiesFile = getAdminFile(path);
1445:                return propertiesFile;
1446:            }
1447:
1448:            protected File getRevertPropertiesFile(String name, boolean tmp) {
1449:                String path = !tmp ? "" : "tmp/";
1450:                path += getThisDirName().equals(name) ? "dir-prop-revert"
1451:                        : "prop-base/" + name + ".svn-revert";
1452:                File propertiesFile = getAdminFile(path);
1453:                return propertiesFile;
1454:            }
1455:
1456:            public File getPropertiesFile(String name, boolean tmp) {
1457:                String path = !tmp ? "" : "tmp/";
1458:                path += getThisDirName().equals(name) ? "dir-props" : "props/"
1459:                        + name + ".svn-work";
1460:                File propertiesFile = getAdminFile(path);
1461:                return propertiesFile;
1462:            }
1463:
1464:            protected Map loadEntries() throws SVNException {
1465:                if (myEntries != null) {
1466:                    return myEntries;
1467:                }
1468:                myEntries = fetchEntries();
1469:                return myEntries;
1470:            }
1471:
1472:            protected Map getBasePropertiesStorage(boolean create) {
1473:                if (myBaseProperties == null && create) {
1474:                    myBaseProperties = new HashMap();
1475:                }
1476:                return myBaseProperties;
1477:            }
1478:
1479:            protected Map getRevertPropertiesStorage(boolean create) {
1480:                if (myRevertProperties == null && create) {
1481:                    myRevertProperties = new HashMap();
1482:                }
1483:                return myRevertProperties;
1484:            }
1485:
1486:            protected Map getPropertiesStorage(boolean create) {
1487:                if (myProperties == null && create) {
1488:                    myProperties = new HashMap();
1489:                }
1490:                return myProperties;
1491:            }
1492:
1493:            protected Map getWCPropertiesStorage(boolean create) {
1494:                if (myWCProperties == null && create) {
1495:                    myWCProperties = new HashMap();
1496:                }
1497:                return myWCProperties;
1498:            }
1499:
1500:            public static String asString(String[] array, String delimiter) {
1501:                String str = null;
1502:                if (array != null) {
1503:                    str = "";
1504:                    for (int i = 0; i < array.length; i++) {
1505:                        str += array[i];
1506:                        if (i < array.length - 1) {
1507:                            str += delimiter;
1508:                        }
1509:                    }
1510:                }
1511:                return str;
1512:            }
1513:
1514:            public static String[] fromString(String str, String delimiter) {
1515:                if (str == null) {
1516:                    return new String[0];
1517:                }
1518:                LinkedList list = new LinkedList();
1519:                int startInd = 0;
1520:                int ind = -1;
1521:                while ((ind = str.indexOf(delimiter, startInd)) != -1) {
1522:                    list.add(str.substring(startInd, ind));
1523:                    startInd = ind;
1524:                    while (startInd < str.length()
1525:                            && str.charAt(startInd) == ' ') {
1526:                        startInd++;
1527:                    }
1528:                }
1529:                if (startInd < str.length()) {
1530:                    list.add(str.substring(startInd));
1531:                }
1532:                return (String[]) list.toArray(new String[list.size()]);
1533:            }
1534:
1535:            private void destroyAdminArea() throws SVNException {
1536:                if (!isLocked()) {
1537:                    SVNErrorMessage err = SVNErrorMessage.create(
1538:                            SVNErrorCode.WC_NOT_LOCKED,
1539:                            "Write-lock stolen in ''{0}''", getRoot());
1540:                    SVNErrorManager.error(err);
1541:                }
1542:                SVNFileUtil.deleteAll(getAdminDirectory(), getWCAccess());
1543:                getWCAccess().closeAdminArea(getRoot());
1544:            }
1545:
1546:            public void commit(String target, SVNCommitInfo info,
1547:                    Map wcPropChanges, boolean removeLock, boolean recursive,
1548:                    Collection explicitCommitPaths, ISVNCommitParameters params)
1549:                    throws SVNException {
1550:
1551:                SVNAdminArea anchor = getWCAccess().retrieve(
1552:                        getWCAccess().getAnchor());
1553:                String path = getRelativePath(anchor);
1554:                path = "".equals(target) ? path : SVNPathUtil.append(path,
1555:                        target);
1556:                if (!explicitCommitPaths.contains(path)) {
1557:                    // if this item is explicitly copied -> skip it.
1558:                    SVNEntry entry = getEntry(target, true);
1559:                    if (entry != null && entry.getCopyFromURL() != null) {
1560:                        return;
1561:                    }
1562:                }
1563:
1564:                SVNLog log = getLog();
1565:                //
1566:                String checksum = null;
1567:                Map command = new HashMap();
1568:                if (!"".equals(target)) {
1569:                    File baseFile = getBaseFile(target, true);
1570:                    SVNFileType baseType = SVNFileType.getType(baseFile);
1571:                    if (baseType == SVNFileType.NONE) {
1572:                        baseFile = getBaseFile(target, false);
1573:                        baseType = SVNFileType.getType(baseFile);
1574:                    }
1575:                    if (baseType == SVNFileType.FILE) {
1576:                        checksum = SVNFileUtil.computeChecksum(baseFile);
1577:                    }
1578:                    File textRevertFile = getFile(SVNAdminUtil
1579:                            .getTextRevertPath(target, false));
1580:                    File propRevertFile = getFile(SVNAdminUtil
1581:                            .getPropRevertPath(target, SVNNodeKind.FILE, false));
1582:                    if (textRevertFile.isFile()) {
1583:                        command.put(SVNLog.NAME_ATTR, SVNAdminUtil
1584:                                .getTextRevertPath(target, false));
1585:                        log.addCommand(SVNLog.DELETE, command, false);
1586:                        command.clear();
1587:                    }
1588:                    if (propRevertFile.isFile()) {
1589:                        command.put(SVNLog.NAME_ATTR, SVNAdminUtil
1590:                                .getPropRevertPath(target, SVNNodeKind.FILE,
1591:                                        false));
1592:                        log.addCommand(SVNLog.DELETE, command, false);
1593:                        command.clear();
1594:                    }
1595:                    command.clear();
1596:                    recursive = false;
1597:                } else {
1598:
1599:                }
1600:                if (info != null) {
1601:                    command.put(SVNLog.NAME_ATTR, target);
1602:                    command.put(SVNProperty
1603:                            .shortPropertyName(SVNProperty.COMMITTED_REVISION),
1604:                            Long.toString(info.getNewRevision()));
1605:                    command.put(SVNProperty
1606:                            .shortPropertyName(SVNProperty.COMMITTED_DATE),
1607:                            SVNTimeUtil.formatDate(info.getDate()));
1608:                    command.put(SVNProperty
1609:                            .shortPropertyName(SVNProperty.LAST_AUTHOR), info
1610:                            .getAuthor());
1611:                    log.addCommand(SVNLog.MODIFY_ENTRY, command, false);
1612:                    command.clear();
1613:                }
1614:                if (checksum != null) {
1615:                    command.put(SVNLog.NAME_ATTR, target);
1616:                    command.put(SVNProperty
1617:                            .shortPropertyName(SVNProperty.CHECKSUM), checksum);
1618:                    log.addCommand(SVNLog.MODIFY_ENTRY, command, false);
1619:                    command.clear();
1620:                }
1621:                if (removeLock) {
1622:                    command.put(SVNLog.NAME_ATTR, target);
1623:                    log.addCommand(SVNLog.DELETE_LOCK, command, false);
1624:                    command.clear();
1625:                }
1626:                command.put(SVNLog.NAME_ATTR, target);
1627:                command.put(SVNLog.REVISION_ATTR, info == null ? null : Long
1628:                        .toString(info.getNewRevision()));
1629:                if (!explicitCommitPaths.contains(path)) {
1630:                    command.put("implicit", "true");
1631:                }
1632:                log.addCommand(SVNLog.COMMIT, command, false);
1633:                command.clear();
1634:                if (wcPropChanges != null && !wcPropChanges.isEmpty()) {
1635:                    for (Iterator propNames = wcPropChanges.keySet().iterator(); propNames
1636:                            .hasNext();) {
1637:                        String propName = (String) propNames.next();
1638:                        String propValue = (String) wcPropChanges.get(propName);
1639:                        command.put(SVNLog.NAME_ATTR, target);
1640:                        command.put(SVNLog.PROPERTY_NAME_ATTR, propName);
1641:                        command.put(SVNLog.PROPERTY_VALUE_ATTR, propValue);
1642:                        log.addCommand(SVNLog.MODIFY_WC_PROPERTY, command,
1643:                                false);
1644:                        command.clear();
1645:                    }
1646:                }
1647:                log.save();
1648:                runLogs();
1649:
1650:                if (recursive) {
1651:                    for (Iterator ents = entries(true); ents.hasNext();) {
1652:                        SVNEntry entry = (SVNEntry) ents.next();
1653:                        if ("".equals(entry.getName())) {
1654:                            continue;
1655:                        }
1656:                        if (entry.getKind() == SVNNodeKind.DIR) {
1657:                            File childPath = getFile(entry.getName());
1658:                            SVNAdminArea childDir = getWCAccess().retrieve(
1659:                                    childPath);
1660:                            if (childDir != null) {
1661:                                childDir.commit("", info, null, removeLock,
1662:                                        true, explicitCommitPaths, params);
1663:                            }
1664:                        } else {
1665:                            commit(entry.getName(), info, null, removeLock,
1666:                                    false, explicitCommitPaths, params);
1667:                        }
1668:                    }
1669:                }
1670:            }
1671:
1672:            protected void setLocked(boolean locked) {
1673:                myWasLocked = locked;
1674:            }
1675:
1676:            public void setCommitParameters(
1677:                    ISVNCommitParameters commitParameters) {
1678:                myCommitParameters = commitParameters;
1679:            }
1680:        }
ww__w_.__j__a__v___a_2__s_.__c__o_m__ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.