dengsixing 11 meses atrás
pai
commit
7dc8d36030
22 arquivos alterados com 22810 adições e 112 exclusões
  1. 7340 0
      src/main/java/com/fdkankan/model/proto/BigSceneProto.java
  2. 4654 0
      src/main/java/com/fdkankan/model/proto/Common.java
  3. 4345 0
      src/main/java/com/fdkankan/model/proto/Visionmodeldata.java
  4. 156 0
      src/main/java/com/fdkankan/model/proto/format/CouchDBFormat.java
  5. 703 0
      src/main/java/com/fdkankan/model/proto/format/HtmlFormat.java
  6. 1338 0
      src/main/java/com/fdkankan/model/proto/format/JavaPropsFormat.java
  7. 1603 0
      src/main/java/com/fdkankan/model/proto/format/JsonFormat.java
  8. 602 0
      src/main/java/com/fdkankan/model/proto/format/SmileFormat.java
  9. 1333 0
      src/main/java/com/fdkankan/model/proto/format/XmlFormat.java
  10. 197 0
      src/main/java/com/fdkankan/model/utils/ConvertUtils.java
  11. 97 0
      src/main/java/com/fdkankan/scene/Interceptor/CheckTokenAspect.java
  12. 10 0
      src/main/java/com/fdkankan/scene/annotation/CheckToken.java
  13. 13 13
      src/main/java/com/fdkankan/scene/controller/SceneEditController.java
  14. 42 0
      src/main/java/com/fdkankan/scene/controller/SceneEditDrawController.java
  15. 2 0
      src/main/java/com/fdkankan/scene/service/FYunFileService.java
  16. 20 0
      src/main/java/com/fdkankan/scene/service/ISceneDrawService.java
  17. 2 2
      src/main/java/com/fdkankan/scene/service/ISceneProService.java
  18. 4 4
      src/main/java/com/fdkankan/scene/service/SceneEditInfoService.java
  19. 15 0
      src/main/java/com/fdkankan/scene/service/impl/FYunFileServiceImpl.java
  20. 234 0
      src/main/java/com/fdkankan/scene/service/impl/SceneDrawServiceImpl.java
  21. 42 41
      src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java
  22. 58 52
      src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java

Diferenças do arquivo suprimidas por serem muito extensas
+ 7340 - 0
src/main/java/com/fdkankan/model/proto/BigSceneProto.java


Diferenças do arquivo suprimidas por serem muito extensas
+ 4654 - 0
src/main/java/com/fdkankan/model/proto/Common.java


Diferenças do arquivo suprimidas por serem muito extensas
+ 4345 - 0
src/main/java/com/fdkankan/model/proto/Visionmodeldata.java


+ 156 - 0
src/main/java/com/fdkankan/model/proto/format/CouchDBFormat.java

@@ -0,0 +1,156 @@
+package com.fdkankan.model.proto.format;
+
+
+import com.google.protobuf.ExtensionRegistry;
+import com.google.protobuf.Message;
+import com.google.protobuf.UnknownFieldSet;
+
+import java.io.IOException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: aantonov
+ * Date: Mar 16, 2010
+ * Time: 4:06:05 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class CouchDBFormat extends JsonFormat {
+
+    /**
+     * Outputs a textual representation of the Protocol Message supplied into the parameter output.
+     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+     * original Protocol Buffer system)
+     */
+    public static void print(Message message, Appendable output) throws IOException {
+        CouchDBGenerator generator = new CouchDBGenerator(output);
+        generator.print("{");
+        print(message, generator);
+        generator.print("}");
+    }
+
+    /**
+     * Outputs a textual representation of {@code fields} to {@code output}.
+     */
+    public static void print(UnknownFieldSet fields, Appendable output) throws IOException {
+        CouchDBGenerator generator = new CouchDBGenerator(output);
+        generator.print("{");
+        printUnknownFields(fields, generator);
+        generator.print("}");
+    }
+
+    /**
+     * Like {@code print()}, but writes directly to a {@code String} and returns it.
+     */
+    public static String printToString(Message message) {
+        try {
+            StringBuilder text = new StringBuilder();
+            print(message, text);
+            return text.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
+                                       e);
+        }
+    }
+
+    /**
+     * Like {@code print()}, but writes directly to a {@code String} and returns it.
+     */
+    public static String printToString(UnknownFieldSet fields) {
+        try {
+            StringBuilder text = new StringBuilder();
+            print(fields, text);
+            return text.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
+                                       e);
+        }
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     */
+    public static void merge(Readable input, Message.Builder builder) throws IOException {
+        merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     */
+    public static void merge(CharSequence input, Message.Builder builder) throws ParseException {
+        merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+     */
+    public static void merge(Readable input,
+                             ExtensionRegistry extensionRegistry,
+                             Message.Builder builder) throws IOException {
+        // Read the entire input to a String then parse that.
+
+        // If StreamTokenizer were not quite so crippled, or if there were a kind
+        // of Reader that could read in chunks that match some particular regex,
+        // or if we wanted to write a custom Reader to tokenize our stream, then
+        // we would not have to read to one big String. Alas, none of these is
+        // the case. Oh well.
+
+        merge(toStringBuilder(input), extensionRegistry, builder);
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+     */
+    public static void merge(CharSequence input,
+                             ExtensionRegistry extensionRegistry,
+                             Message.Builder builder) throws ParseException {
+        Tokenizer tokenizer = new Tokenizer(input);
+
+        // Based on the state machine @ http://json.org/
+
+        tokenizer.consume("{"); // Needs to happen when the object starts.
+        while (!tokenizer.tryConsume("}")) { // Continue till the object is done
+            mergeField(tokenizer, extensionRegistry, builder);
+        }
+    }
+
+    protected static class Tokenizer extends JsonFormat.Tokenizer {
+
+        /**
+         * Construct a tokenizer that parses tokens from the given text.
+         */
+        public Tokenizer(CharSequence text) {
+            super(text);
+        }
+
+        @Override
+        public String consumeIdentifier() throws ParseException {
+            String id = super.consumeIdentifier();
+            if ("_id".equals(id)) {
+                return "id";
+            } else if ("_rev".equals(id)) {
+                return "rev";
+            }
+            return id;
+        }
+    }
+
+    protected static class CouchDBGenerator extends JsonGenerator {
+
+        public CouchDBGenerator(Appendable output) {
+            super(output);
+        }
+
+        @Override
+        public void print(CharSequence text) throws IOException {
+            if ("id".equals(text)) {
+                super.print("_id");
+            } else if ("rev".equals(text)) {
+                super.print("_rev");
+            } else {
+                super.print(text);
+            }
+        }
+    }
+}

+ 703 - 0
src/main/java/com/fdkankan/model/proto/format/HtmlFormat.java

@@ -0,0 +1,703 @@
+package com.fdkankan.model.proto.format;
+/* 
+    Copyright (c) 2009, Orbitz World Wide
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+    are permitted provided that the following conditions are met:
+
+        * Redistributions of source code must retain the above copyright notice, 
+          this list of conditions and the following disclaimer.
+        * Redistributions in binary form must reproduce the above copyright notice, 
+          this list of conditions and the following disclaimer in the documentation 
+          and/or other materials provided with the distribution.
+        * Neither the name of the Orbitz World Wide nor the names of its contributors 
+          may be used to endorse or promote products derived from this software 
+          without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Message;
+import com.google.protobuf.UnknownFieldSet;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Provide ascii html formatting support for proto2 instances.
+ * <p>
+ * (c) 2009-10 Orbitz World Wide. All Rights Reserved.
+ * 
+ * @author eliran.bivas@gmail.com Eliran Bivas
+ * @version $HtmlFormat.java Mar 12, 2009 4:00:33 PM$
+ */
+public final class HtmlFormat {
+
+    private static final String META_CONTENT = "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" />";
+    private static final String MAIN_DIV_STYLE = "color: black; font-size: 14px; font-family: sans-serif; font-weight: bolder; margin-bottom: 10px;";
+    private static final String FIELD_NAME_STYLE = "font-weight: bold; color: #669966;font-size: 14px; font-family: sans-serif;";
+    private static final String FIELD_VALUE_STYLE = "color: #3300FF;font-size: 13px; font-family: sans-serif;";
+
+    /**
+     * Outputs a textual representation of the Protocol Message supplied into the parameter output.
+     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+     * original Protocol Buffer system)
+     */
+    public static void print(Message message, Appendable output) throws IOException {
+        HtmlGenerator generator = new HtmlGenerator(output);
+        printTitle(message, generator);
+        print(message, generator);
+        generator.print("</body></html>");
+    }
+
+    private static void printTitle(final Message message, final HtmlGenerator generator) throws IOException {
+        generator.print("<html><head>");
+        generator.print(META_CONTENT);
+        generator.print("<title>");
+        generator.print(message.getDescriptorForType().getFullName());
+        generator.print("</title></head><body>");
+        generator.print("<div style=\"");
+        generator.print(MAIN_DIV_STYLE);
+        generator.print("\">message : ");
+        generator.print(message.getDescriptorForType().getFullName());
+        generator.print("</div>");
+    }
+
+    /**
+     * Outputs a textual representation of {@code fields} to {@code output}.
+     */
+    public static void print(UnknownFieldSet fields, Appendable output) throws IOException {
+        HtmlGenerator generator = new HtmlGenerator(output);
+        generator.print("<html>");
+        generator.print(META_CONTENT);
+        generator.print("</head><body>");
+        printUnknownFields(fields, generator);
+        generator.print("</body></html>");
+    }
+
+    /**
+     * Like {@code print()}, but writes directly to a {@code String} and returns it.
+     */
+    public static String printToString(Message message) {
+        try {
+            StringBuilder text = new StringBuilder();
+            print(message, text);
+            return text.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
+                                       e);
+        }
+    }
+
+    /**
+     * Like {@code print()}, but writes directly to a {@code String} and returns it.
+     */
+    public static String printToString(UnknownFieldSet fields) {
+        try {
+            StringBuilder text = new StringBuilder();
+            print(fields, text);
+            return text.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
+                                       e);
+        }
+    }
+
+    private static void print(Message message, HtmlGenerator generator) throws IOException {
+
+        for (Map.Entry<FieldDescriptor, Object> field : message.getAllFields().entrySet()) {
+            printField(field.getKey(), field.getValue(), generator);
+        }
+        printUnknownFields(message.getUnknownFields(), generator);
+    }
+
+    public static void printField(FieldDescriptor field, Object value, HtmlGenerator generator) throws IOException {
+
+        if (field.isRepeated()) {
+            // Repeated field. Print each element.
+            for (Object element : (List<?>) value) {
+                printSingleField(field, element, generator);
+            }
+        } else {
+            printSingleField(field, value, generator);
+        }
+    }
+
+    private static void printSingleField(FieldDescriptor field,
+                                         Object value,
+                                         HtmlGenerator generator) throws IOException {
+        if (field.isExtension()) {
+            generator.print("[<span style=\"");
+            generator.print(FIELD_NAME_STYLE);
+            generator.print("\">");
+            // We special-case MessageSet elements for compatibility with proto1.
+            if (field.getContainingType().getOptions().getMessageSetWireFormat()
+                            && (field.getType() == FieldDescriptor.Type.MESSAGE) && (field.isOptional())
+                            // object equality
+                            && (field.getExtensionScope() == field.getMessageType())) {
+                generator.print(field.getMessageType().getFullName());
+            } else {
+                generator.print(field.getFullName());
+            }
+            generator.print("</span>]");
+        } else {
+            generator.print("<span style=\"");
+            generator.print(FIELD_NAME_STYLE);
+            generator.print("\">");
+            if (field.getType() == FieldDescriptor.Type.GROUP) {
+                // Groups must be serialized with their original capitalization.
+                generator.print(field.getMessageType().getName());
+            } else {
+                generator.print(field.getName());
+            }
+            generator.print("</span>");
+        }
+
+        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+            generator.print(" <span style=\"color: red;\">{</span><br/>");
+            generator.indent();
+        } else {
+            generator.print(": ");
+        }
+
+        printFieldValue(field, value, generator);
+
+        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+            generator.outdent();
+            generator.print("<span style=\"color: red;\">}</span>");
+        }
+        generator.print("<br/>");
+    }
+
+    private static void printFieldValue(FieldDescriptor field, Object value, HtmlGenerator generator) throws IOException {
+        generator.print("<span style=\"");
+        generator.print(FIELD_VALUE_STYLE);
+        generator.print("\">");
+        switch (field.getType()) {
+            case INT32:
+            case INT64:
+            case SINT32:
+            case SINT64:
+            case SFIXED32:
+            case SFIXED64:
+            case FLOAT:
+            case DOUBLE:
+            case BOOL:
+                // Good old toString() does what we want for these types.
+                generator.print(value.toString());
+                break;
+
+            case UINT32:
+            case FIXED32:
+                generator.print(unsignedToString((Integer) value));
+                break;
+
+            case UINT64:
+            case FIXED64:
+                generator.print(unsignedToString((Long) value));
+                break;
+
+            case STRING:
+                generator.print("\"");
+                generator.print(value.toString());
+                generator.print("\"");
+                break;
+
+            case BYTES: {
+                generator.print("\"");
+                generator.print(escapeBytes((ByteString) value));
+                generator.print("\"");
+                break;
+            }
+
+            case ENUM: {
+                generator.print(((EnumValueDescriptor) value).getName());
+                break;
+            }
+
+            case MESSAGE:
+            case GROUP:
+                print((Message) value, generator);
+                break;
+        }
+        generator.print("</span>");
+    }
+
+    private static void printUnknownFields(UnknownFieldSet unknownFields, HtmlGenerator generator) throws IOException {
+        for (Map.Entry<Integer, UnknownFieldSet.Field> entry : unknownFields.asMap().entrySet()) {
+            UnknownFieldSet.Field field = entry.getValue();
+
+            for (long value : field.getVarintList()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": ");
+                generator.print(unsignedToString(value));
+                generator.print("<br/>");
+            }
+            for (int value : field.getFixed32List()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": ");
+                generator.print(String.format((Locale) null, "0x%08x", value));
+                generator.print("<br/>");
+            }
+            for (long value : field.getFixed64List()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": ");
+                generator.print(String.format((Locale) null, "0x%016x", value));
+                generator.print("<br/>");
+            }
+            for (ByteString value : field.getLengthDelimitedList()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": \"");
+                generator.print(escapeBytes(value));
+                generator.print("\"<br/>");
+            }
+            for (UnknownFieldSet value : field.getGroupList()) {
+                generator.print(entry.getKey().toString());
+                generator.print(" <span style=\"color: red;\">{</span><br/>");
+                generator.indent();
+                printUnknownFields(value, generator);
+                generator.outdent();
+                generator.print("<span style=\"color: red;\">}</span><br/>");
+            }
+        }
+    }
+
+    /**
+     * Convert an unsigned 32-bit integer to a string.
+     */
+    private static String unsignedToString(int value) {
+        if (value >= 0) {
+            return Integer.toString(value);
+        } else {
+            return Long.toString((value) & 0x00000000FFFFFFFFL);
+        }
+    }
+
+    /**
+     * Convert an unsigned 64-bit integer to a string.
+     */
+    private static String unsignedToString(long value) {
+        if (value >= 0) {
+            return Long.toString(value);
+        } else {
+            // Pull off the most-significant bit so that BigInteger doesn't think
+            // the number is negative, then set it again using setBit().
+            return BigInteger.valueOf(value & 0x7FFFFFFFFFFFFFFFL).setBit(63).toString();
+        }
+    }
+
+    /**
+     * An inner class for writing text to the output stream.
+     */
+    static private final class HtmlGenerator {
+
+        Appendable output;
+        boolean atStartOfLine = true;
+
+        public HtmlGenerator(Appendable output) {
+            this.output = output;
+        }
+
+        /**
+         * Indent text by two spaces. After calling Indent(), two spaces will be inserted at the
+         * beginning of each line of text. Indent() may be called multiple times to produce deeper
+         * indents.
+         * 
+         * @throws IOException
+         */
+        public void indent() throws IOException {
+            print("<div style=\"margin-left: 25px\">");
+        }
+
+        /**
+         * Reduces the current indent level by two spaces, or crashes if the indent level is zero.
+         * 
+         * @throws IOException
+         */
+        public void outdent() throws IOException {
+            print("</div>");
+        }
+
+        /**
+         * Print text to the output stream.
+         */
+        public void print(CharSequence text) throws IOException {
+            int size = text.length();
+            int pos = 0;
+
+            for (int i = 0; i < size; i++) {
+                if (text.charAt(i) == '\n') {
+                    write("<br/>", i - pos + 1);
+                    pos = i + 1;
+                    atStartOfLine = true;
+                }
+            }
+            write(text.subSequence(pos, size), size - pos);
+        }
+
+        private void write(CharSequence data, int size) throws IOException {
+            if (size == 0) {
+                return;
+            }
+            if (atStartOfLine) {
+                atStartOfLine = false;
+            }
+            output.append(data);
+        }
+    }
+
+    // =================================================================
+    // Utility functions
+    //
+    // Some of these methods are package-private because Descriptors.java uses
+    // them.
+
+    /**
+     * Escapes bytes in the format used in protocol buffer text format, which is the same as the
+     * format used for C string literals. All bytes that are not printable 7-bit ASCII characters
+     * are escaped, as well as backslash, single-quote, and double-quote characters. Characters for
+     * which no defined short-hand escape sequence is defined will be escaped using 3-digit octal
+     * sequences.
+     */
+    static String escapeBytes(ByteString input) {
+        StringBuilder builder = new StringBuilder(input.size());
+        for (int i = 0; i < input.size(); i++) {
+            byte b = input.byteAt(i);
+            switch (b) {
+                // Java does not recognize \a or \v, apparently.
+                case 0x07:
+                    builder.append("\\a");
+                    break;
+                case '\b':
+                    builder.append("\\b");
+                    break;
+                case '\f':
+                    builder.append("\\f");
+                    break;
+                case '\n':
+                    builder.append("\\n");
+                    break;
+                case '\r':
+                    builder.append("\\r");
+                    break;
+                case '\t':
+                    builder.append("\\t");
+                    break;
+                case 0x0b:
+                    builder.append("\\v");
+                    break;
+                case '\\':
+                    builder.append("\\\\");
+                    break;
+                case '\'':
+                    builder.append("\\\'");
+                    break;
+                case '"':
+                    builder.append("\\\"");
+                    break;
+                default:
+                    if (b >= 0x20) {
+                        builder.append((char) b);
+                    } else {
+                        builder.append('\\');
+                        builder.append((char) ('0' + ((b >>> 6) & 3)));
+                        builder.append((char) ('0' + ((b >>> 3) & 7)));
+                        builder.append((char) ('0' + (b & 7)));
+                    }
+                    break;
+            }
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Un-escape a byte sequence as escaped using
+     * {@link #escapeBytes(com.googlecode.protobuf.format.ByteString)}. Two-digit hex escapes (starting with
+     * "\x") are also recognized.
+     */
+    static ByteString unescapeBytes(CharSequence input) throws InvalidEscapeSequence {
+        byte[] result = new byte[input.length()];
+        int pos = 0;
+        for (int i = 0; i < input.length(); i++) {
+            char c = input.charAt(i);
+            if (c == '\\') {
+                if (i + 1 < input.length()) {
+                    ++i;
+                    c = input.charAt(i);
+                    if (isOctal(c)) {
+                        // Octal escape.
+                        int code = digitValue(c);
+                        if ((i + 1 < input.length()) && isOctal(input.charAt(i + 1))) {
+                            ++i;
+                            code = code * 8 + digitValue(input.charAt(i));
+                        }
+                        if ((i + 1 < input.length()) && isOctal(input.charAt(i + 1))) {
+                            ++i;
+                            code = code * 8 + digitValue(input.charAt(i));
+                        }
+                        result[pos++] = (byte) code;
+                    } else {
+                        switch (c) {
+                            case 'a':
+                                result[pos++] = 0x07;
+                                break;
+                            case 'b':
+                                result[pos++] = '\b';
+                                break;
+                            case 'f':
+                                result[pos++] = '\f';
+                                break;
+                            case 'n':
+                                result[pos++] = '\n';
+                                break;
+                            case 'r':
+                                result[pos++] = '\r';
+                                break;
+                            case 't':
+                                result[pos++] = '\t';
+                                break;
+                            case 'v':
+                                result[pos++] = 0x0b;
+                                break;
+                            case '\\':
+                                result[pos++] = '\\';
+                                break;
+                            case '\'':
+                                result[pos++] = '\'';
+                                break;
+                            case '"':
+                                result[pos++] = '\"';
+                                break;
+
+                            case 'x':
+                                // hex escape
+                                int code = 0;
+                                if ((i + 1 < input.length()) && isHex(input.charAt(i + 1))) {
+                                    ++i;
+                                    code = digitValue(input.charAt(i));
+                                } else {
+                                    throw new InvalidEscapeSequence("Invalid escape sequence: '\\x' with no digits");
+                                }
+                                if ((i + 1 < input.length()) && isHex(input.charAt(i + 1))) {
+                                    ++i;
+                                    code = code * 16 + digitValue(input.charAt(i));
+                                }
+                                result[pos++] = (byte) code;
+                                break;
+
+                            default:
+                                throw new InvalidEscapeSequence("Invalid escape sequence: '\\" + c
+                                                                + "'");
+                        }
+                    }
+                } else {
+                    throw new InvalidEscapeSequence("Invalid escape sequence: '\\' at end of string.");
+                }
+            } else {
+                result[pos++] = (byte) c;
+            }
+        }
+
+        return ByteString.copyFrom(result, 0, pos);
+    }
+
+    /**
+     * Thrown by {@link JsonFormat#unescapeBytes} and {@link JsonFormat#unescapeText} when an
+     * invalid escape sequence is seen.
+     */
+    static class InvalidEscapeSequence extends IOException {
+
+        private static final long serialVersionUID = 1L;
+
+        public InvalidEscapeSequence(String description) {
+            super(description);
+        }
+    }
+
+    /**
+     * Like {@link #escapeBytes(com.googlecode.protobuf.format.ByteString)}, but escapes a text string.
+     * Non-ASCII characters are first encoded as UTF-8, then each byte is escaped individually as a
+     * 3-digit octal escape. Yes, it's weird.
+     */
+    static String escapeText(String input) {
+        return escapeBytes(ByteString.copyFromUtf8(input));
+    }
+
+    /**
+     * Un-escape a text string as escaped using {@link #escapeText(String)}. Two-digit hex escapes
+     * (starting with "\x") are also recognized.
+     */
+    static String unescapeText(String input) throws InvalidEscapeSequence {
+        return unescapeBytes(input).toStringUtf8();
+    }
+
+    /**
+     * Is this an octal digit?
+     */
+    private static boolean isOctal(char c) {
+        return ('0' <= c) && (c <= '7');
+    }
+
+    /**
+     * Is this a hex digit?
+     */
+    private static boolean isHex(char c) {
+        return (('0' <= c) && (c <= '9')) || (('a' <= c) && (c <= 'f'))
+        || (('A' <= c) && (c <= 'F'));
+    }
+
+    /**
+     * Interpret a character as a digit (in any base up to 36) and return the numeric value. This is
+     * like {@code Character.digit()} but we don't accept non-ASCII digits.
+     */
+    private static int digitValue(char c) {
+        if (('0' <= c) && (c <= '9')) {
+            return c - '0';
+        } else if (('a' <= c) && (c <= 'z')) {
+            return c - 'a' + 10;
+        } else {
+            return c - 'A' + 10;
+        }
+    }
+
+    /**
+     * Parse a 32-bit signed integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively.
+     */
+    static int parseInt32(String text) throws NumberFormatException {
+        return (int) parseInteger(text, true, false);
+    }
+
+    /**
+     * Parse a 32-bit unsigned integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively. The result is coerced to a (signed) {@code int}
+     * when returned since Java has no unsigned integer type.
+     */
+    static int parseUInt32(String text) throws NumberFormatException {
+        return (int) parseInteger(text, false, false);
+    }
+
+    /**
+     * Parse a 64-bit signed integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively.
+     */
+    static long parseInt64(String text) throws NumberFormatException {
+        return parseInteger(text, true, true);
+    }
+
+    /**
+     * Parse a 64-bit unsigned integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively. The result is coerced to a (signed) {@code long}
+     * when returned since Java has no unsigned long type.
+     */
+    static long parseUInt64(String text) throws NumberFormatException {
+        return parseInteger(text, false, true);
+    }
+
+    private static long parseInteger(String text, boolean isSigned, boolean isLong) throws NumberFormatException {
+        int pos = 0;
+
+        boolean negative = false;
+        if (text.startsWith("-", pos)) {
+            if (!isSigned) {
+                throw new NumberFormatException("Number must be positive: " + text);
+            }
+            ++pos;
+            negative = true;
+        }
+
+        int radix = 10;
+        if (text.startsWith("0x", pos)) {
+            pos += 2;
+            radix = 16;
+        } else if (text.startsWith("0", pos)) {
+            radix = 8;
+        }
+
+        String numberText = text.substring(pos);
+
+        long result = 0;
+        if (numberText.length() < 16) {
+            // Can safely assume no overflow.
+            result = Long.parseLong(numberText, radix);
+            if (negative) {
+                result = -result;
+            }
+
+            // Check bounds.
+            // No need to check for 64-bit numbers since they'd have to be 16 chars
+            // or longer to overflow.
+            if (!isLong) {
+                if (isSigned) {
+                    if ((result > Integer.MAX_VALUE) || (result < Integer.MIN_VALUE)) {
+                        throw new NumberFormatException("Number out of range for 32-bit signed integer: "
+                                                        + text);
+                    }
+                } else {
+                    if ((result >= (1L << 32)) || (result < 0)) {
+                        throw new NumberFormatException("Number out of range for 32-bit unsigned integer: "
+                                                        + text);
+                    }
+                }
+            }
+        } else {
+            BigInteger bigValue = new BigInteger(numberText, radix);
+            if (negative) {
+                bigValue = bigValue.negate();
+            }
+
+            // Check bounds.
+            if (!isLong) {
+                if (isSigned) {
+                    if (bigValue.bitLength() > 31) {
+                        throw new NumberFormatException("Number out of range for 32-bit signed integer: "
+                                                        + text);
+                    }
+                } else {
+                    if (bigValue.bitLength() > 32) {
+                        throw new NumberFormatException("Number out of range for 32-bit unsigned integer: "
+                                                        + text);
+                    }
+                }
+            } else {
+                if (isSigned) {
+                    if (bigValue.bitLength() > 63) {
+                        throw new NumberFormatException("Number out of range for 64-bit signed integer: "
+                                                        + text);
+                    }
+                } else {
+                    if (bigValue.bitLength() > 64) {
+                        throw new NumberFormatException("Number out of range for 64-bit unsigned integer: "
+                                                        + text);
+                    }
+                }
+            }
+
+            result = bigValue.longValue();
+        }
+
+        return result;
+    }
+}

Diferenças do arquivo suprimidas por serem muito extensas
+ 1338 - 0
src/main/java/com/fdkankan/model/proto/format/JavaPropsFormat.java


Diferenças do arquivo suprimidas por serem muito extensas
+ 1603 - 0
src/main/java/com/fdkankan/model/proto/format/JsonFormat.java


+ 602 - 0
src/main/java/com/fdkankan/model/proto/format/SmileFormat.java

@@ -0,0 +1,602 @@
+//package com.fdkankan.model.proto.format;
+///*
+//	Copyright (c) 2009, Orbitz World Wide
+//	All rights reserved.
+//
+//	Redistribution and use in source and binary forms, with or without modification,
+//	are permitted provided that the following conditions are met:
+//
+//		* Redistributions of source code must retain the above copyright notice,
+//		  this list of conditions and the following disclaimer.
+//		* Redistributions in binary form must reproduce the above copyright notice,
+//		  this list of conditions and the following disclaimer in the documentation
+//		  and/or other materials provided with the distribution.
+//		* Neither the name of the Orbitz World Wide nor the names of its contributors
+//		  may be used to endorse or promote products derived from this software
+//		  without specific prior written permission.
+//
+//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//	LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+//	A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+//	OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+//	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+//	LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+//	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+//	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+//	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+//	OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//*/
+//
+//
+//import com.google.protobuf.*;
+//import com.google.protobuf.Descriptors.Descriptor;
+//import com.google.protobuf.Descriptors.EnumDescriptor;
+//import com.google.protobuf.Descriptors.EnumValueDescriptor;
+//import com.google.protobuf.Descriptors.FieldDescriptor;
+//import org.codehaus.jackson.JsonGenerator;
+//import org.codehaus.jackson.JsonParseException;
+//import org.codehaus.jackson.JsonParser;
+//import org.codehaus.jackson.JsonToken;
+//import org.codehaus.jackson.smile.SmileFactory;
+//import org.codehaus.jackson.smile.SmileGenerator;
+//import org.codehaus.jackson.smile.SmileParser;
+//
+//import java.io.IOException;
+//import java.io.InputStream;
+//import java.io.OutputStream;
+//import java.math.BigInteger;
+//import java.util.Iterator;
+//import java.util.List;
+//import java.util.Locale;
+//import java.util.Map;
+//import java.util.regex.Pattern;
+//
+///**
+// * Provide ascii text parsing and formatting support for proto2 instances. The implementation
+// * largely follows google/protobuf/text_format.cc.
+// * <p>
+// * (c) 2011 Neustar, Inc. All Rights Reserved.
+// *
+// * @author jeffrey.damick@neustar.biz Jeffrey Damick
+// *         Based on the original code by:
+// * @author eliran.bivas@gmail.com Eliran Bivas
+// * @author aantonov@orbitz.com Alex Antonov
+// *         <p/>
+// * @author wenboz@google.com Wenbo Zhu
+// * @author kenton@google.com Kenton Varda
+// */
+//public class SmileFormat {
+//    private static SmileFactory smileFactory = new SmileFactory();
+//
+//
+//    /**
+//     * Outputs a Smile representation of the Protocol Message supplied into the parameter output.
+//     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+//     * original Protocol Buffer system)
+//     */
+//    public static void print(Message message, OutputStream output) throws IOException {
+//        JsonGenerator generator = createGenerator(output);
+//    	print(message, generator);
+//    	generator.close();
+//    }
+//
+//    /**
+//     * Outputs a Smile representation of the Protocol Message supplied into the parameter output.
+//     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+//     * original Protocol Buffer system)
+//     */
+//    public static void print(Message message, JsonGenerator generator) throws IOException {
+//    	generator.writeStartObject();
+//    	printMessage(message, generator);
+//        generator.writeEndObject();
+//        generator.flush();
+//    }
+//
+//    /**
+//     * Outputs a Smile representation of {@code fields} to {@code output}.
+//     */
+//    public static void print(UnknownFieldSet fields, OutputStream output) throws IOException {
+//    	JsonGenerator generator = createGenerator(output);
+//    	generator.writeStartObject();
+//    	printUnknownFields(fields, generator);
+//        generator.writeEndObject();
+//        generator.close();
+//    }
+//
+//
+//
+//    /**
+//     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+//     */
+//    public static void merge(InputStream input, Message.Builder builder) throws IOException {
+//        merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+//    }
+//
+//
+//    /**
+//     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+//     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+//     * @throws IOException
+//     */
+//    public static void merge(InputStream input,
+//                             ExtensionRegistry extensionRegistry,
+//                             Message.Builder builder) throws IOException {
+//
+//    	SmileParser parser = smileFactory.createJsonParser(input);
+//    	merge(parser, extensionRegistry, builder);
+//    }
+//
+//    /**
+//     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+//     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+//     * @throws IOException
+//     */
+//    public static void merge(JsonParser parser,
+//    						 ExtensionRegistry extensionRegistry,
+//                             Message.Builder builder) throws IOException {
+//
+//        JsonToken token = parser.nextToken();
+//        if (token.equals(JsonToken.START_OBJECT)) {
+//        	token = parser.nextToken();
+//        }
+//        while (token != null && !token.equals(JsonToken.END_OBJECT)) {
+//        	mergeField(parser, extensionRegistry, builder);
+//        	token = parser.nextToken();
+//        }
+//
+//        // Test to make sure the tokenizer has reached the end of the stream.
+//        if (parser.nextToken() != null) {
+//            throw new RuntimeException("Expecting the end of the stream, but there seems to be more data!  Check the input for a valid JSON format.");
+//        }
+//    }
+//
+//
+//
+//    protected static JsonGenerator createGenerator(OutputStream output) throws IOException {
+//    	SmileGenerator generator = smileFactory.createJsonGenerator(output);
+//    	generator.enable(SmileGenerator.Feature.WRITE_HEADER);
+//    	generator.enable(SmileGenerator.Feature.WRITE_END_MARKER);
+//    	return generator;
+//    }
+//
+//
+//    protected static void printMessage(Message message, JsonGenerator generator) throws IOException {
+//
+//        for (Iterator<Map.Entry<FieldDescriptor, Object>> iter = message.getAllFields().entrySet().iterator(); iter.hasNext();) {
+//            Map.Entry<FieldDescriptor, Object> field = iter.next();
+//            printField(field.getKey(), field.getValue(), generator);
+//        }
+//        printUnknownFields(message.getUnknownFields(), generator);
+//    }
+//
+//    public static void printField(FieldDescriptor field, Object value, JsonGenerator generator) throws IOException {
+//
+//        printSingleField(field, value, generator);
+//    }
+//
+//    private static void printSingleField(FieldDescriptor field,
+//                                         Object value,
+//                                         JsonGenerator generator) throws IOException {
+//        if (field.isExtension()) {
+//            // We special-case MessageSet elements for compatibility with proto1.
+//            if (field.getContainingType().getOptions().getMessageSetWireFormat()
+//                && (field.getType() == FieldDescriptor.Type.MESSAGE) && (field.isOptional())
+//                // object equality
+//                && (field.getExtensionScope() == field.getMessageType())) {
+//                generator.writeFieldName(field.getMessageType().getFullName());
+//            } else {
+//            	// extensions will have '.' in them, while normal fields wont..
+//            	generator.writeFieldName(field.getFullName());
+//            }
+//        } else {
+//            if (field.getType() == FieldDescriptor.Type.GROUP) {
+//                // Groups must be serialized with their original capitalization.
+//                generator.writeFieldName(field.getMessageType().getName());
+//            } else {
+//                generator.writeFieldName(field.getName());
+//            }
+//        }
+//
+//        // Done with the name, on to the value
+//        if (field.isRepeated()) {
+//            // Repeated field. Print each element.
+//            generator.writeStartArray();
+//            for (Iterator<?> iter = ((List<?>) value).iterator(); iter.hasNext();) {
+//                printFieldValue(field, iter.next(), generator);
+//            }
+//            generator.writeEndArray();
+//        } else {
+//            printFieldValue(field, value, generator);
+//        }
+//    }
+//
+//    private static void printFieldValue(FieldDescriptor field, Object value, JsonGenerator generator) throws IOException {
+//    	// TODO: look at using field.getType().getJavaType(), to simplify this..
+//    	switch (field.getType()) {
+//            case INT32:
+//            case SINT32:
+//            case SFIXED32:
+//            	generator.writeNumber((Integer)value);
+//            	break;
+//
+//            case INT64:
+//            case SINT64:
+//            case SFIXED64:
+//            	generator.writeNumber((Long)value);
+//            	break;
+//
+//            case FLOAT:
+//            	generator.writeNumber((Float)value);
+//            	break;
+//
+//            case DOUBLE:
+//            	generator.writeNumber((Double)value);
+//            	break;
+//
+//            case BOOL:
+//                // Good old toString() does what we want for these types.
+//                generator.writeBoolean((Boolean)value);
+//                break;
+//
+//            case UINT32:
+//            case FIXED32:
+//                generator.writeNumber(unsignedInt((Integer) value));
+//                break;
+//
+//            case UINT64:
+//            case FIXED64:
+//                generator.writeNumber(unsignedLong((Long) value));
+//                break;
+//
+//            case STRING:
+//            	generator.writeString((String) value);
+//                break;
+//
+//            case BYTES: {
+//            	// Here we break with JsonFormat - since there is an issue with non-utf8 bytes..
+//            	generator.writeBinary(((ByteString)value).toByteArray());
+//                break;
+//            }
+//
+//            case ENUM: {
+//            	generator.writeString(((EnumValueDescriptor) value).getName());
+//                break;
+//            }
+//
+//            case MESSAGE:
+//            case GROUP:
+//            	generator.writeStartObject();
+//                printMessage((Message) value, generator);
+//                generator.writeEndObject();
+//                break;
+//        }
+//    }
+//
+//    protected static void printUnknownFields(UnknownFieldSet unknownFields, JsonGenerator generator) throws IOException {
+//        for (Map.Entry<Integer, UnknownFieldSet.Field> entry : unknownFields.asMap().entrySet()) {
+//            UnknownFieldSet.Field field = entry.getValue();
+//
+//            generator.writeArrayFieldStart(entry.getKey().toString());
+//            for (long value : field.getVarintList()) {
+//                generator.writeNumber(value);
+//            }
+//            for (int value : field.getFixed32List()) {
+//                generator.writeNumber(value);
+//            }
+//            for (long value : field.getFixed64List()) {
+//                generator.writeNumber(value);
+//            }
+//            for (ByteString value : field.getLengthDelimitedList()) {
+//            	// here we break with the JsonFormat to support non-utf8 bytes
+//            	generator.writeBinary(value.toByteArray());
+//            }
+//            for (UnknownFieldSet value : field.getGroupList()) {
+//                generator.writeStartObject();
+//                printUnknownFields(value, generator);
+//                generator.writeEndObject();
+//            }
+//            generator.writeEndArray();
+//        }
+//    }
+//
+//
+//
+//    // =================================================================
+//    // Parsing
+//
+//    private static final Pattern DIGITS = Pattern.compile(
+//          "[0-9]",
+//          Pattern.CASE_INSENSITIVE);
+//
+//    /**
+//     * Parse a single field from {@code parser} and merge it into {@code builder}. If a ',' is
+//     * detected after the field ends, the next field will be parsed automatically
+//     * @throws IOException
+//     * @throws JsonParseException
+//     */
+//    protected static void mergeField(JsonParser parser,
+//                                   ExtensionRegistry extensionRegistry,
+//                                   Message.Builder builder) throws JsonParseException, IOException {
+//        FieldDescriptor field = null;
+//        Descriptor type = builder.getDescriptorForType();
+//        boolean unknown = false;
+//        ExtensionRegistry.ExtensionInfo extension = null;
+//        JsonToken token = parser.getCurrentToken();
+//
+//        if (token != null) {
+//            String name = parser.getCurrentName();
+//
+//            if (name.contains(".")) {
+//            	// should be an extension
+//            	extension = extensionRegistry.findExtensionByName(name);
+//                if (extension == null) {
+//                    throw new RuntimeException("Extension \""
+//                    		+ name + "\" not found in the ExtensionRegistry.");
+//                } else if (extension.descriptor.getContainingType() != type) {
+//                    throw new RuntimeException("Extension \"" + name
+//                    		+ "\" does not extend message type \""
+//                    		+ type.getFullName() + "\".");
+//                }
+//
+//            	field = extension.descriptor;
+//            } else {
+//            	field = type.findFieldByName(name);
+//            }
+//
+//            // Group names are expected to be capitalized as they appear in the
+//            // .proto file, which actually matches their type names, not their field
+//            // names.
+//            if (field == null) {
+//                // Explicitly specify US locale so that this code does not break when
+//                // executing in Turkey.
+//                String lowerName = name.toLowerCase(Locale.US);
+//                field = type.findFieldByName(lowerName);
+//                // If the case-insensitive match worked but the field is NOT a group,
+//                if ((field != null) && (field.getType() != FieldDescriptor.Type.GROUP)) {
+//                    field = null;
+//                }
+//            }
+//            // Again, special-case group names as described above.
+//            if ((field != null) && (field.getType() == FieldDescriptor.Type.GROUP)
+//                && !field.getMessageType().getName().equals(name)
+//                && !field.getMessageType().getFullName().equalsIgnoreCase(name) /* extension */) {
+//                field = null;
+//            }
+//
+//            // Last try to lookup by field-index if 'name' is numeric,
+//            // which indicates a possible unknown field
+//            if (field == null && DIGITS.matcher(name).matches()) {
+//                field = type.findFieldByNumber(Integer.parseInt(name));
+//                unknown = true;
+//            }
+//
+//            // no throwing exceptions if field not found, since it could be a different version.
+//            if (field == null) {
+//            	UnknownFieldSet.Builder unknownsBuilder = UnknownFieldSet.newBuilder();
+//            	handleMissingField(name, parser, extensionRegistry, unknownsBuilder);
+//            	builder.setUnknownFields(unknownsBuilder.build());
+//            }
+//        }
+//
+//        if (field != null) {
+//        	token = parser.nextToken();
+//
+//            boolean array = token.equals(JsonToken.START_ARRAY);
+//
+//            if (array) {
+//            	token = parser.nextToken();
+//                while (!token.equals(JsonToken.END_ARRAY)) {
+//                    handleValue(parser, extensionRegistry, builder, field, extension, unknown);
+//                    token = parser.nextToken();
+//                }
+//            } else {
+//                handleValue(parser, extensionRegistry, builder, field, extension, unknown);
+//            }
+//        }
+//    }
+//
+//    private static void handleMissingField(String fieldName, JsonParser parser,
+//                                           ExtensionRegistry extensionRegistry,
+//                                           UnknownFieldSet.Builder builder) throws IOException {
+//
+//        JsonToken token = parser.nextToken();
+//        if (token.equals(JsonToken.START_OBJECT)) {
+//            // Message structure
+//        	token = parser.nextToken(); // skip name
+//        	while (token != null && !token.equals(JsonToken.END_OBJECT)) {
+//                handleMissingField(fieldName, parser, extensionRegistry, builder);
+//                token = parser.nextToken(); // get } or field name
+//            }
+//        } else if (token.equals(JsonToken.START_ARRAY)) {
+//            // Collection
+//            do {
+//                handleMissingField(fieldName, parser, extensionRegistry, builder);
+//                token = parser.getCurrentToken(); // got value or ]
+//            } while (token != null && !token.equals(JsonToken.END_ARRAY));
+//        } else {
+//            // Primitive value
+//        	// NULL, INT, BOOL, STRING
+//        	// nothing to do..
+//        }
+//    }
+//
+//    private static void handleValue(JsonParser parser,
+//                                    ExtensionRegistry extensionRegistry,
+//                                    Message.Builder builder,
+//                                    FieldDescriptor field,
+//                                    ExtensionRegistry.ExtensionInfo extension,
+//                                    boolean unknown) throws IOException {
+//
+//        Object value = null;
+//        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+//            value = handleObject(parser, extensionRegistry, builder, field, extension, unknown);
+//        } else {
+//            value = handlePrimitive(parser, field);
+//        }
+//        if (value != null) {
+//            if (field.isRepeated()) {
+//                builder.addRepeatedField(field, value);
+//            } else {
+//                builder.setField(field, value);
+//            }
+//        }
+//    }
+//
+//    private static Object handlePrimitive(JsonParser parser, FieldDescriptor field) throws IOException {
+//        Object value = null;
+//
+//        JsonToken token = parser.getCurrentToken();
+//
+//        if (token.equals(JsonToken.VALUE_NULL)) {
+//            return value;
+//        }
+//
+//        switch (field.getType()) {
+//            case INT32:
+//            case SINT32:
+//            case SFIXED32:
+//            	value = parser.getIntValue();
+//                break;
+//
+//            case INT64:
+//            case SINT64:
+//            case SFIXED64:
+//            	value = parser.getLongValue();
+//                break;
+//
+//            case UINT32:
+//            case FIXED32:
+//            	int valueInt = parser.getIntValue();
+//            	if (valueInt < 0) {
+//            		throw new NumberFormatException("Number must be positive: " + valueInt);
+//            	}
+//            	value = valueInt;
+//                break;
+//
+//            case UINT64:
+//            case FIXED64:
+//            	long valueLong = parser.getLongValue();
+//            	if (valueLong < 0) {
+//            		throw new NumberFormatException("Number must be positive: " + valueLong);
+//            	}
+//            	value = valueLong;
+//                break;
+//
+//            case FLOAT:
+//            	value = parser.getFloatValue();
+//                break;
+//
+//            case DOUBLE:
+//            	value = parser.getDoubleValue();
+//                break;
+//
+//            case BOOL:
+//            	value = parser.getBooleanValue();
+//                break;
+//
+//            case STRING:
+//            	value = parser.getText();
+//                break;
+//
+//            case BYTES:
+//            	value = ByteString.copyFrom(parser.getBinaryValue());
+//                break;
+//
+//            case ENUM: {
+//                EnumDescriptor enumType = field.getEnumType();
+//                if (token.equals(JsonToken.VALUE_NUMBER_INT)) {
+//                    int number = parser.getIntValue();
+//                    value = enumType.findValueByNumber(number);
+//                    if (value == null) {
+//                        throw new RuntimeException("Enum type \""
+//                        		+ enumType.getFullName()
+//                        		+ "\" has no value with number "
+//                        		+ number + ".");
+//                    }
+//                } else {
+//                    String id = parser.getText();
+//                    value = enumType.findValueByName(id);
+//                    if (value == null) {
+//                    	throw new RuntimeException("Enum type \""
+//                    			+ enumType.getFullName()
+//                    			+ "\" has no value named \""
+//                    			+ id + "\".");
+//                    }
+//                }
+//                break;
+//            }
+//
+//            case MESSAGE:
+//            case GROUP:
+//                throw new RuntimeException("Can't get here.");
+//        }
+//        return value;
+//    }
+//
+//
+//    private static Object handleObject(JsonParser parser,
+//                                       ExtensionRegistry extensionRegistry,
+//                                       Message.Builder builder,
+//                                       FieldDescriptor field,
+//                                       ExtensionRegistry.ExtensionInfo extension,
+//                                       boolean unknown) throws IOException {
+//
+//        Message.Builder subBuilder;
+//        if (extension == null) {
+//            subBuilder = builder.newBuilderForField(field);
+//        } else {
+//            subBuilder = extension.defaultInstance.newBuilderForType();
+//        }
+//
+//        JsonToken token = parser.getCurrentToken();
+//
+//        if (unknown) {
+//        	ByteString data = ByteString.copyFrom(parser.getBinaryValue());
+//            try {
+//                subBuilder.mergeFrom(data);
+//                return subBuilder.build();
+//            } catch (InvalidProtocolBufferException e) {
+//                throw new RuntimeException("Failed to build " + field.getFullName() + " from " + data);
+//            }
+//        }
+//
+//        //token = parser.nextToken();
+//        if (token.equals(JsonToken.START_OBJECT)) {
+//	        token = parser.nextToken();
+//	        while (token != null && !token.equals(JsonToken.END_OBJECT)) {
+//	            mergeField(parser, extensionRegistry, subBuilder);
+//	            token = parser.nextToken();
+//	        }
+//        }
+//        return subBuilder.build();
+//    }
+//
+//    // =================================================================
+//    // Utility functions
+//    //
+//    // Some of these methods are package-private because Descriptors.java uses
+//    // them.
+//
+//    /**
+//     * Convert an unsigned 32-bit integer to a string.
+//     */
+//    private static Integer unsignedInt(int value) {
+//        if (value < 0) {
+//            return (int) ((value) & 0x00000000FFFFFFFFL);
+//        }
+//        return value;
+//    }
+//
+//    /**
+//     * Convert an unsigned 64-bit integer to a string.
+//     */
+//    private static Long unsignedLong(long value) {
+//        if (value < 0) {
+//            // Pull off the most-significant bit so that BigInteger doesn't think
+//            // the number is negative, then set it again using setBit().
+//            return BigInteger.valueOf(value & 0x7FFFFFFFFFFFFFFFL).setBit(63).longValue();
+//        }
+//        return value;
+//    }
+//}

Diferenças do arquivo suprimidas por serem muito extensas
+ 1333 - 0
src/main/java/com/fdkankan/model/proto/format/XmlFormat.java


+ 197 - 0
src/main/java/com/fdkankan/model/utils/ConvertUtils.java

@@ -0,0 +1,197 @@
+package com.fdkankan.model.utils;
+
+import com.fdkankan.model.proto.Visionmodeldata;
+import com.fdkankan.model.proto.format.JsonFormat;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+public class ConvertUtils {
+
+    public static void convertVisionModelDataToTxt(String srcPath, String desPath) throws Exception {
+
+        BufferedOutputStream bos = null;
+        BufferedInputStream bis = null;
+        try {
+            File file = new File(srcPath);
+            FileInputStream fis = new FileInputStream(file);
+
+            Visionmodeldata.NavigationInfo data_NavigationInfo = Visionmodeldata.NavigationInfo.parseFrom(fis);
+
+            String jsonFormat1 = JsonFormat.printToString(data_NavigationInfo);
+            ByteArrayInputStream stream = new ByteArrayInputStream(jsonFormat1.getBytes());
+            bos = new BufferedOutputStream(new FileOutputStream(desPath));//设置输出路径
+            bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            //out.close();
+            fis.close();
+            stream.close();
+            bis.close();
+            bos.close();
+        } catch (Exception e) {
+            StringWriter trace = new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        } finally {
+            if (bos != null) {
+                bos.close();
+            }
+            if (bis != null) {
+                bis.close();
+            }
+        }
+    }
+
+    public static void convertTxtToVisionModelData(String srcPath, String desPath) throws Exception {
+        BufferedOutputStream bos = null;
+        BufferedInputStream bis = null;
+        try {
+            Visionmodeldata.NavigationInfo.Builder builder = Visionmodeldata.NavigationInfo.newBuilder();
+            String jsonFormat = readTxtFileToJson(srcPath);
+            JsonFormat.merge(jsonFormat, builder);
+            byte[] buf = builder.build().toByteArray();
+
+            //把序列化后的数据写入本地磁盘
+            ByteArrayInputStream stream = new ByteArrayInputStream(buf);
+            bos = new BufferedOutputStream(new FileOutputStream(desPath));//设置输出路径
+            bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            bis.close();
+            bos.close();
+        } catch (Exception e) {
+            StringWriter trace = new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        } finally {
+            if (bos != null) {
+                bos.close();
+            }
+            if (bis != null) {
+                bis.close();
+            }
+        }
+    }
+
+    public static String readTxtFileToJson(String filePath) {
+        try {
+            String encoding = "UTF-8";
+            File file = new File(filePath);
+            if (file.isFile() && file.exists()) {
+                InputStreamReader read = new InputStreamReader(
+                        new FileInputStream(file), encoding);
+                BufferedReader bufferedReader = new BufferedReader(read);
+                String lineTxt = null;
+                String result = "";
+                while ((lineTxt = bufferedReader.readLine()) != null) {
+                    result += lineTxt;
+                }
+                read.close();
+                return result;
+            } else {
+                return null;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+    public List<List<String>> descartes(List<List<String>> dimValue) {
+        List<List<String>> res = new ArrayList<>();
+        if (dimValue == null || dimValue.size() == 0)
+            return res;
+        backtrace(dimValue, 0, res, new ArrayList<>());
+        return res;
+
+    }
+
+    /**
+     * 递归回溯法求解
+     *
+     * @param dimValue 原始数据集合
+     * @param index 当前执行的集合索引
+     * @param result 结果集合
+     * @param curList 当前的单个结果集
+     */
+    private void backtrace(List<List<String>> dimValue, int index,
+                           List<List<String>> result, List<String> curList) {
+
+        if (curList.size() == dimValue.size())
+            result.add(new ArrayList<>(curList));
+        else
+            for (int j = 0; j < dimValue.get(index).size(); j++) {
+                curList.add(dimValue.get(index).get(j));
+                backtrace(dimValue, index + 1, result, curList);
+                curList.remove(curList.size() - 1);
+            }
+
+    }
+
+    public static void convertTxtToVisionmodeldata(String srcpath,String despath)throws Exception
+    {
+        try
+        {
+            Visionmodeldata.NavigationInfo.Builder builder = Visionmodeldata.NavigationInfo.newBuilder();
+            String jsonFormat = readTxtFileToJson(srcpath);
+            JsonFormat.merge(jsonFormat, builder);
+            byte[] buf= builder.build().toByteArray();
+
+            //把序列化后的数据写入本地磁盘
+            ByteArrayInputStream stream = new ByteArrayInputStream(buf);
+            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径
+            BufferedInputStream bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            bis.close();
+            bos.close();
+        }
+        catch(Exception e)
+        {
+            StringWriter trace=new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        }
+    }
+
+    public static void convertVisionmodeldataToTxt(String srcpath,String despath)throws Exception
+    {
+        try
+        {
+            File file = new File(srcpath);
+            FileInputStream fis=new FileInputStream(file);
+
+            Visionmodeldata.NavigationInfo data_NavigationInfo = Visionmodeldata.NavigationInfo.parseFrom(fis);
+
+            //PrintStream out = new PrintStream(despath);
+            String jsonFormat1 = JsonFormat.printToString(data_NavigationInfo);
+            ByteArrayInputStream stream = new ByteArrayInputStream(jsonFormat1.getBytes());
+            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径
+            BufferedInputStream bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            //out.close();
+            bis.close();
+            bos.close();
+        }
+        catch(Exception e)
+        {
+            StringWriter trace=new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        }
+    }
+}

+ 97 - 0
src/main/java/com/fdkankan/scene/Interceptor/CheckTokenAspect.java

@@ -0,0 +1,97 @@
+package com.fdkankan.scene.Interceptor;
+
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.ThreeDESUtil;
+import com.fdkankan.common.util.UserAgentUtils;
+import com.fdkankan.common.util.WebUtil;
+import com.fdkankan.feign.TietaFeignClient;
+import com.fdkankan.feign.WS4AServiceClient;
+import com.fdkankan.scene.entity.SceneViewLog;
+import com.fdkankan.scene.service.SceneViewLogService;
+import lombok.extern.log4j.Log4j2;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Log4j2
+@Aspect
+@Component
+@Order(101)
+public class CheckTokenAspect {
+
+	@Value("${spring.cloud.nacos.discovery.access-key}")
+	private String accessKey;
+
+	@Value("${tieta.checkToken.syscode}")
+	private String syscode;
+	@Value("${gateway.key:6#dPz>3F}")
+	private String gatewayKey;
+	@Value("${gateway.url}")
+	private String gatewayUrl;
+	@Resource
+	private TietaFeignClient tietaFeignClient;
+	@Autowired
+	private WS4AServiceClient ws4AServiceClient;
+	@Autowired
+	private SceneViewLogService sceneViewLogService;
+
+	@Pointcut("@annotation(com.fdkankan.scene.annotation.CheckToken)")
+	public void CheckToken() {
+	}
+
+	/**
+	 * 前置通知 用于判断用户协作场景是否有协作权限
+	 *
+	 * @param joinPoint
+	 *            切点
+	 * @throws IOException
+	 */
+	@Before("CheckToken()")
+	public void doBefore(JoinPoint joinPoint) throws Exception {
+		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+		//请求4a接口获取用户信息
+		Map<String, Object> parameter = WebUtil.getParameter(joinPoint, request);
+		String acctId = (String) parameter.get("acctId");
+		String token = (String) parameter.get("token");
+		String num = (String) parameter.get("num");
+
+		//token校验
+		JSONObject checkProwadaTokenParam = new JSONObject();
+		JSONObject params = new JSONObject();
+		params.put("SYSCODE", syscode);
+		params.put("ACCTID", acctId);
+		params.put("TOKEN", token);
+		String encode = ThreeDESUtil.encode(JSON.toJSONString(params), gatewayKey);
+		checkProwadaTokenParam.put("args", encode);
+		JSONObject result = ws4AServiceClient.checkProwadaToken(checkProwadaTokenParam);
+		log.info("场景:{},4A校验token结果:{}", num, result);
+		if(!"SUCCESS".equals(result.getString("resultStat"))){
+			throw new BusinessException(4000, "4A鉴权失败");
+		}
+		String data = result.getString("data");
+		JSONObject dataObj = JSONObject.parseObject(data);
+		if(!"0".equals(dataObj.getString("RSP"))){
+			throw new BusinessException(4000, "4A鉴权失败:" + dataObj.getString("ERRDESC"));
+		}
+	}
+
+}

+ 10 - 0
src/main/java/com/fdkankan/scene/annotation/CheckToken.java

@@ -0,0 +1,10 @@
+package com.fdkankan.scene.annotation;
+
+import java.lang.annotation.*;
+
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface CheckToken {
+    String description() default "";
+}

+ 13 - 13
src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -145,19 +145,19 @@ public class SceneEditController{
         return sceneProService.deleteIcons(param);
     }
 
-//    /**
-//     * <p>
-//     保存漫游可行
-//     * </p>
-//     * @author dengsixing
-//     * @date 2022/1/12
-//     * @param param
-//     * @return com.fdkankan.web.response.ResultData
-//     **/
-//    @PostMapping(value = "/saveRoam")
-//    public ResultData saveRoam(@RequestBody @Validated BaseDataParamVO param) throws Exception {
-//        return sceneProService.saveRoam(param);
-//    }
+    /**
+     * <p>
+     保存漫游可行
+     * </p>
+     * @author dengsixing
+     * @date 2022/1/12
+     * @param param
+     * @return com.fdkankan.web.response.ResultData
+     **/
+    @PostMapping(value = "/saveRoam")
+    public ResultData saveRoam(@RequestBody @Validated BaseDataParamVO param) throws Exception {
+        return sceneProService.saveRoam(param);
+    }
 
     /**
      * <p>

+ 42 - 0
src/main/java/com/fdkankan/scene/controller/SceneEditDrawController.java

@@ -0,0 +1,42 @@
+package com.fdkankan.scene.controller;
+
+import com.fdkankan.scene.bean.ResultData;
+import com.fdkankan.scene.service.ISceneDrawService;
+import com.fdkankan.scene.vo.BaseJsonArrayParamVO;
+import com.fdkankan.scene.vo.DeleteSidListParamVO;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 场景编辑管理
+ */
+@Log4j2
+@RestController
+@RequestMapping("/service/scene/edit/sceneDraw")
+public class SceneEditDrawController{
+
+    @Autowired
+    private ISceneDrawService sceneDrawService;
+
+    @GetMapping(value = "/list")
+    public ResultData listSceneDraw(@RequestParam("num") String num) throws Exception {
+        return ResultData.ok(sceneDrawService.listSceneDraw(num));
+    }
+
+    @PostMapping(value = "/save")
+    public ResultData saveSceneDraw(@RequestBody @Validated BaseJsonArrayParamVO param) throws Exception {
+        sceneDrawService.saveSceneDraw(param);
+        return ResultData.ok();
+    }
+
+    @PostMapping(value = "/delete")
+    public ResultData deleteSceneDraw(@RequestBody @Validated DeleteSidListParamVO param) throws Exception {
+        sceneDrawService.deleteSceneDraw(param);
+        return ResultData.ok();
+    }
+
+
+
+}

+ 2 - 0
src/main/java/com/fdkankan/scene/service/FYunFileService.java

@@ -8,4 +8,6 @@ public interface FYunFileService {
 
     void uploadFile(String num, byte[] data, String key);
 
+    void uploadFile(String num, String path, String key);
+
 }

+ 20 - 0
src/main/java/com/fdkankan/scene/service/ISceneDrawService.java

@@ -0,0 +1,20 @@
+package com.fdkankan.scene.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.scene.vo.BaseJsonArrayParamVO;
+import com.fdkankan.scene.vo.DeleteSidListParamVO;
+
+import java.io.IOException;
+import java.util.List;
+
+public interface ISceneDrawService {
+
+    void saveSceneDraw(BaseJsonArrayParamVO param) throws Exception;
+
+    List<JSONObject> listSceneDraw(String num) throws Exception;
+
+    void deleteSceneDraw(DeleteSidListParamVO param) throws Exception;
+
+    void publicSceneDraw(String sceneNum) throws IOException;
+
+}

+ 2 - 2
src/main/java/com/fdkankan/scene/service/ISceneProService.java

@@ -23,8 +23,8 @@ public interface ISceneProService{
 
     ResultData listTags(String num) throws Exception;
 
-//    ResultData saveRoam(BaseDataParamVO param) throws Exception;
-//
+    ResultData saveRoam(BaseDataParamVO param) throws Exception;
+
     ResultData saveTagsVisible(SaveTagsVisibleParamVO param) throws Exception;
 //
 //    void updateUserIdByCameraId(Long userId, Long cameraId);

+ 4 - 4
src/main/java/com/fdkankan/scene/service/SceneEditInfoService.java

@@ -43,10 +43,10 @@ public interface SceneEditInfoService extends IService<SceneEditInfo> {
     ResultData renameCad(RenameCadParamVO param) throws IOException;
 //
     void upgradeVersionById(Long id);
-//
-//    void upgradeVersionAndImgVersionById(Long id);
-//
-//    void upgradeSceneJsonVersion(String num, int version, Integer imgVersion, String bucket) throws IOException ;
+
+    void upgradeVersionAndImgVersionById(Long id);
+
+    void upgradeSceneJsonVersion(String num, int version, Integer imgVersion) throws IOException ;
 //
 //    ResultData uploadPanorama(String num, MultipartFile file) throws Exception;
 //

+ 15 - 0
src/main/java/com/fdkankan/scene/service/impl/FYunFileServiceImpl.java

@@ -58,6 +58,21 @@ public class FYunFileServiceImpl implements FYunFileService {
         sceneFileMappingService.saveOrUpdate(sceneFileMapping);
     }
 
+    @Override
+    public void uploadFile(String num, String path, String key) {
+        Map<String, String> mapping = fdfsUtil.uploadFile(path);
+        //添加记录
+        SceneFileMapping sceneFileMapping =  sceneFileMappingService.getByKey(key);
+        if(Objects.isNull(sceneFileMapping)){
+            sceneFileMapping = new SceneFileMapping();
+        }
+        sceneFileMapping.setNum(num);
+        sceneFileMapping.setFileid(mapping.get("file_id"));
+        sceneFileMapping.setUrl(mapping.get("http_url"));
+        sceneFileMapping.setKey(key);
+        sceneFileMappingService.saveOrUpdate(sceneFileMapping);
+    }
+
     public static void main(String[] args) {
         String suffix = "." + FileUtil.getSuffix("/sxx/ttt/adf.json");
         File tempFile = FileUtil.createTempFile(UUID.fastUUID().toString(), suffix, new File("D:\\test2"), true);

+ 234 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneDrawServiceImpl.java

@@ -0,0 +1,234 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.fdkankan.common.constant.CommonStatus;
+import com.fdkankan.common.constant.UploadFilePath;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisClient;
+import com.fdkankan.scene.bean.TagBean;
+import com.fdkankan.scene.entity.Scene;
+import com.fdkankan.scene.entity.SceneEditInfoExt;
+import com.fdkankan.scene.service.*;
+import com.fdkankan.scene.vo.BaseJsonArrayParamVO;
+import com.fdkankan.scene.vo.DeleteSidListParamVO;
+import com.google.common.collect.Lists;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+public class SceneDrawServiceImpl implements ISceneDrawService {
+
+    private final String SCENE_DRAW_JSON_NAME = "sceneDraw.json";
+
+    @Autowired
+    private SceneService sceneService;
+    @Autowired
+    private RedisClient redisClient;
+    @Autowired
+    private SceneEditInfoExtService sceneEditInfoExtService;
+    @Autowired
+    private SceneEditInfoService sceneEditInfoService;
+    @Resource
+    private FYunFileService fYunFileService;
+    @Autowired
+    private SceneFileMappingService sceneFileMappingService;
+
+    @Override
+    public void saveSceneDraw(BaseJsonArrayParamVO param) throws Exception {
+
+        Scene scenePlus = sceneService.getByNum(param.getNum());
+
+        this.addOrUpdate(param.getNum(), param.getData());
+
+        //保存数据库
+        SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
+        this.updateDb(param.getNum(), scenePlus.getId());
+
+        sceneEditInfoService.upgradeVersionById(sceneEditInfoExt.getEditInfoId());
+
+        this.publicSceneDraw(param.getNum());
+    }
+
+    private void updateDb(String num, Long scenePlusId){
+        //查询缓存是否包含热点数据
+        String key = String.format(RedisKey.SCENE_DRAW, num);
+        Map<String, String> map = redisClient.hmget(key);
+        boolean hasSceneDraw= false;
+        for (Map.Entry<String, String> tagMap : map.entrySet()) {
+            if(StrUtil.isEmpty(tagMap.getValue())){
+                continue;
+            }
+            hasSceneDraw = true;
+            break;
+        }
+
+        //更改热点状态
+        sceneEditInfoExtService.update(
+                new LambdaUpdateWrapper<SceneEditInfoExt>()
+                        .set(SceneEditInfoExt::getSceneDraw, hasSceneDraw ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue())
+                        .eq(SceneEditInfoExt::getScenePlusId,scenePlusId));
+    }
+
+    private void addOrUpdate(String num, List<JSONObject> data) throws Exception{
+        Map<String, String> addOrUpdateMap = new HashMap<>();
+        int i = 0;
+        for (JSONObject jsonObject : data) {
+            jsonObject.put("createTime", Calendar.getInstance().getTimeInMillis() + i++);
+            addOrUpdateMap.put(jsonObject.getString("sid"), JSON.toJSONString(jsonObject));
+        }
+
+//        this.syncFileToRedis(num);
+
+        //处理新增和修改数据
+        this.addOrUpdateHandler(num, addOrUpdateMap);
+    }
+
+    private void addOrUpdateHandler(String num, Map<String, String> addOrUpdateMap){
+        if(CollUtil.isEmpty(addOrUpdateMap))
+            return;
+
+        //批量写入缓存
+        String key = String.format(RedisKey.SCENE_DRAW, num);
+        redisClient.hmset(key, addOrUpdateMap);
+
+        //写入本地文件,作为备份
+//        this.writeFile(num);
+    }
+
+//    private void writeFile(String num){
+//        String lockKey = String.format(RedisLockKey.LOCK_SCENE_DRAW, num);
+//        String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString();
+//        boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE);
+//        if(!lock){
+//            return;
+//        }
+//        try{
+//            String dataKey = String.format(RedisKey.SCENE_DRAW, num);
+//            String sceneDrawJsonPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + SCENE_DRAW_JSON_NAME;
+//            if(!redisUtil.hasKey(dataKey)){
+//                FileUtil.del(sceneDrawJsonPath);
+//                return;
+//            }
+//            Map<String, String> map = redisUtil.hmget(dataKey);
+//            List<JSONObject>  list = map.entrySet().stream().map(entry->JSON.parseObject(entry.getValue())).collect(Collectors.toList());
+//            FileUtil.writeUtf8String(JSON.toJSONString(list), sceneDrawJsonPath);
+//        }finally {
+//            redisLockUtil.unlockLua(lockKey, lockVal);
+//        }
+//    }
+
+//    private void syncFileToRedis(String num) throws Exception{
+//
+//        String key = String.format(RedisKey.SCENE_DRAW, num);
+//        boolean exist = redisUtil.hasKey(key);
+//        if(exist){
+//            return;
+//        }
+//        String lockKey = String.format(RedisLockKey.LOCK_SCENE_DRAW, num);
+//        String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString();
+//        boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE);
+//        if(!lock){
+//            throw new BusinessException(ErrorCode.SYSTEM_BUSY);
+//        }
+//        try{
+//            exist = redisUtil.hasKey(key);
+//            if(exist){
+//                return;
+//            }
+//            String sceneDrawFilePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + SCENE_DRAW_JSON_NAME;
+//            String sceneDrawData = FileUtils.readUtf8String(sceneDrawFilePath);
+//            if(StrUtil.isEmpty(sceneDrawData)){
+//                return;
+//            }
+//            JSONArray tagsArr = JSON.parseArray(sceneDrawData);
+//            if(CollUtil.isEmpty(tagsArr)){
+//                return;
+//            }
+//            Map<String, String> map = new HashMap<>();
+//            for (Object o : tagsArr) {
+//                JSONObject jo = (JSONObject)o;
+//                map.put(jo.getString("sid"), jo.toJSONString());
+//            }
+//            redisUtil.hmset(key, map);
+//        }finally {
+//            redisLockUtil.unlockLua(lockKey, lockVal);
+//        }
+//    }
+
+    @Override
+    public List<JSONObject> listSceneDraw(String num) throws Exception {
+        List<JSONObject> tags = new ArrayList<>();
+//        this.syncFileToRedis(num);
+
+        //获取裁剪模型数据
+        String key = String.format(RedisKey.SCENE_DRAW, num);
+        List<String> list = redisClient.hgetValues(key);
+        if(CollUtil.isNotEmpty(list)){
+            List<TagBean> sortList = list.stream().map(str -> {
+                JSONObject jsonObject = JSON.parseObject(str);
+                TagBean tagBean = new TagBean();
+                tagBean.setCreateTime(jsonObject.getLong("createTime"));
+                jsonObject.remove("createTime");
+                tagBean.setTag(jsonObject);
+                return tagBean;
+            }).collect(Collectors.toList());
+            sortList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed());
+            tags = sortList.stream().map(item -> item.getTag()).collect(Collectors.toList());
+        }
+
+        return tags;
+    }
+
+    @Override
+    public void deleteSceneDraw(DeleteSidListParamVO param) throws Exception {
+        Scene scenePlus = sceneService.getByNum(param.getNum());
+        List<String> deleteSidList = param.getSidList();
+//        this.syncFileToRedis(param.getNum());
+        //处理删除状态数据
+        this.deleteCache(param.getNum(), deleteSidList);
+        //写入本地文件,作为备份
+//        this.writeFile(param.getNum());
+        //保存数据库
+        SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
+        this.updateDb(param.getNum(), scenePlus.getId());
+        sceneEditInfoService.upgradeVersionById(sceneEditInfoExt.getEditInfoId());
+
+        this.publicSceneDraw(param.getNum());
+    }
+
+    private List<String> deleteCache(String num, List<String> deleteSidList) {
+        if(CollUtil.isEmpty(deleteSidList)){
+            return null;
+        }
+
+        //从redis中加载热点数据
+        String key = String.format(RedisKey.SCENE_DRAW, num);
+        List<String> deletDataList = redisClient.hMultiGet(key, deleteSidList);
+        if(CollUtil.isNotEmpty(deletDataList)){
+            redisClient.hdel(key, deletDataList);
+        }
+        return deletDataList;
+    }
+
+    @Override
+    public void publicSceneDraw(String sceneNum) throws IOException {
+        String Key = String.format(RedisKey.SCENE_DRAW, sceneNum);
+        String userEditPath = String.format(UploadFilePath.USER_VIEW_PATH, sceneNum) + SCENE_DRAW_JSON_NAME;
+        List<String> list = redisClient.hgetValues(Key);
+        if(CollUtil.isEmpty(list)){
+            sceneFileMappingService.delByNumAndKey(sceneNum, userEditPath);
+            return;
+        }
+        List<JSONObject> collect = list.stream().map(str -> JSON.parseObject(str)).collect(Collectors.toList());
+        fYunFileService.uploadFile(sceneNum, JSON.toJSONString(collect).getBytes(), userEditPath);
+    }
+}

+ 42 - 41
src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java

@@ -15,6 +15,7 @@ import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.util.RedisClient;
 import com.fdkankan.scene.bean.ResultData;
+import com.fdkankan.scene.bean.SceneJsonBean;
 import com.fdkankan.scene.bean.TagBean;
 import com.fdkankan.scene.entity.*;
 import com.fdkankan.scene.mapper.SceneEditInfoMapper;
@@ -931,47 +932,47 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<SceneEditInfoMapper, S
                 .setSql("version=version+" + 1)
                 .eq(SceneEditInfo::getId, id));
     }
-//
-//    @Override
-//    public void upgradeVersionAndImgVersionById(Long id) {
-//        this.update(new LambdaUpdateWrapper<SceneEditInfo>()
-//                .setSql("version=version + " + 1)
-//                .setSql("img_version=img_version + " + 1)
-//                .eq(SceneEditInfo::getId, id));
-//    }
-//
-//    @Override
-//    public void upgradeSceneJsonVersion(String num, int version, Integer imgVersion, String bucket) throws IOException {
-//
-//        //更新redis缓存版本号
-//        String key = String.format(RedisKey.SCENE_JSON, num);
-//        String sceneJson = redisUtil.get(key);
-//        if(StrUtil.isNotEmpty(sceneJson)){
-//            SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
-//            if(Objects.nonNull(version)){
-//                sceneJsonBean.setVersion(version);
-//            }
-//            if(Objects.nonNull(imgVersion)){
-//                sceneJsonBean.setImgVersion(imgVersion);
-//            }
-//            redisUtil.set(key, JSON.toJSONString(sceneJsonBean));
-//        }
-//
-//        //更新oss scene.json版本号
-//        String sceneJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "scene.json";
-//        sceneJson= fYunFileService.getFileContent(bucket, sceneJsonPath);
-//        if(StrUtil.isNotEmpty(sceneJson)){
-//            SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
-//            if(Objects.nonNull(version)){
-//                sceneJsonBean.setVersion(version);
-//            }
-//            if(Objects.nonNull(imgVersion)){
-//                sceneJsonBean.setImgVersion(imgVersion);
-//            }
-//            fYunFileService.uploadFile(bucket, JSON.toJSONString(sceneJsonBean).getBytes(StandardCharsets.UTF_8), sceneJsonPath);
-//        }
-//
-//    }
+
+    @Override
+    public void upgradeVersionAndImgVersionById(Long id) {
+        this.update(new LambdaUpdateWrapper<SceneEditInfo>()
+                .setSql("version=version + " + 1)
+                .setSql("img_version=img_version + " + 1)
+                .eq(SceneEditInfo::getId, id));
+    }
+
+    @Override
+    public void upgradeSceneJsonVersion(String num, int version, Integer imgVersion) throws IOException {
+
+        //更新redis缓存版本号
+        String key = String.format(RedisKey.SCENE_JSON, num);
+        String sceneJson = redisClient.get(key);
+        if(StrUtil.isNotEmpty(sceneJson)){
+            SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
+            if(Objects.nonNull(version)){
+                sceneJsonBean.setVersion(version);
+            }
+            if(Objects.nonNull(imgVersion)){
+                sceneJsonBean.setImgVersion(imgVersion);
+            }
+            redisClient.add(key, JSON.toJSONString(sceneJsonBean));
+        }
+
+        //更新oss scene.json版本号
+        String sceneJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "scene.json";
+        sceneJson= fYunFileService.getFileContent(sceneJsonPath);
+        if(StrUtil.isNotEmpty(sceneJson)){
+            SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
+            if(Objects.nonNull(version)){
+                sceneJsonBean.setVersion(version);
+            }
+            if(Objects.nonNull(imgVersion)){
+                sceneJsonBean.setImgVersion(imgVersion);
+            }
+            fYunFileService.uploadFile(num, JSON.toJSONString(sceneJsonBean).getBytes(StandardCharsets.UTF_8), sceneJsonPath);
+        }
+
+    }
 //
 //    @Override
 //    public ResultData uploadPanorama(String num, MultipartFile file) throws Exception {

+ 58 - 52
src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java

@@ -1,6 +1,7 @@
 package com.fdkankan.scene.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
@@ -10,6 +11,7 @@ import com.fdkankan.common.constant.ConstantFilePath;
 import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.constant.UploadFilePath;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.model.utils.ConvertUtils;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.util.RedisClient;
 import com.fdkankan.scene.bean.IconBean;
@@ -558,25 +560,24 @@ public class SceneProServiceImpl implements ISceneProService {
         return ResultData.ok();
     }
 
-//    @Override
-//    public ResultData saveRoam(BaseDataParamVO param) throws Exception {
-//
-//        Scene scenePlus = scenePlusService.getByNum(param.getNum());
-//        if (scenePlus == null ) {
-//            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
-//        }
-//
-//        JSONArray inputData = JSONObject.parseArray(param.getData());
-//
-//        String localDataPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, param.getNum());
-//        File directory = new File(localDataPath);
-//        if (!directory.exists()) {
-//            directory.mkdirs();
-//        }
-//        String viewImagesPath = String.format(UploadFilePath.IMG_VIEW_PATH, param.getNum());
-//        String modeldataUrl = ossUrlPrefix + viewImagesPath + "vision.modeldata?t=" + System.currentTimeMillis();
-//
-//        //如果是云存储,将vision.modeldata下载到本地,如果是本地存储,场景计算完就已经将这个文件拷贝到编辑目录了存在这个文件了,不需要再下载
+    @Override
+    public ResultData saveRoam(BaseDataParamVO param) throws Exception {
+
+        Scene scenePlus = scenePlusService.getByNum(param.getNum());
+        if (scenePlus == null ) {
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+        }
+
+        JSONArray inputData = JSONObject.parseArray(param.getData());
+
+        String localDataPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, param.getNum());
+        File directory = new File(localDataPath);
+        if (!directory.exists()) {
+            directory.mkdirs();
+        }
+        String viewImagesPath = String.format(UploadFilePath.IMG_VIEW_PATH, param.getNum());
+
+        //如果是云存储,将vision.modeldata下载到本地,如果是本地存储,场景计算完就已经将这个文件拷贝到编辑目录了存在这个文件了,不需要再下载
 //        fYunFileService.downloadFile(bucket, viewImagesPath + "vision.modeldata", localDataPath + "vision.modeldata");
 //
 //        //检查vision.modeldata本地是否存在,不存在抛出异常
@@ -586,43 +587,48 @@ public class SceneProServiceImpl implements ISceneProService {
 //        }
 //        //将vision.modeldata解压缩至vision.json
 //        ConvertUtils.convertVisionModelDataToTxt(localDataPath + "vision.modeldata", localDataPath + "vision.json");
-//
+
 //        String str = FileUtils.readFile(localDataPath + "vision.json");
-//        JSONObject json = JSONObject.parseObject(str);
-//        JSONArray panos = json.getJSONArray("sweepLocations");
-//        for (int i = 0; i < panos.size(); ++i) {
-//            JSONObject pano = panos.getJSONObject(i);
-//            for (int j = 0; j < inputData.size(); ++j) {
-//                JSONObject jo = inputData.getJSONObject(j);
-//                String currentPanoId = jo.getString("panoID");
-//                JSONArray visibles = jo.getJSONArray("visibles");
-//                JSONArray visibles3 = jo.getJSONArray("visibles3");
-//                if (pano.getString("uuid").replaceAll("-", "").equals(currentPanoId)) {
-//                    pano.put("visibles", visibles);
-//                    pano.put("visibles3", visibles3);
-//                }
-//            }
-//        }
+
+        String str = fYunFileService.getFileContent(viewImagesPath + "vision.txt");
+        JSONObject json = JSONObject.parseObject(str);
+        JSONArray panos = json.getJSONArray("sweepLocations");
+        for (int i = 0; i < panos.size(); ++i) {
+            JSONObject pano = panos.getJSONObject(i);
+            for (int j = 0; j < inputData.size(); ++j) {
+                JSONObject jo = inputData.getJSONObject(j);
+                String currentPanoId = jo.getString("panoID");
+                JSONArray visibles = jo.getJSONArray("visibles");
+                JSONArray visibles3 = jo.getJSONArray("visibles3");
+                if (pano.getString("uuid").replaceAll("-", "").equals(currentPanoId)) {
+                    pano.put("visibles", visibles);
+                    pano.put("visibles3", visibles3);
+                }
+            }
+        }
 //        FileUtils.deleteFile(localDataPath + "vision.json");
 //        FileUtils.deleteFile(localDataPath + "vision.modeldata");
 //        FileUtils.writeFile(localDataPath + "vision.json", json.toString());
-//        ConvertUtils.convertTxtToVisionModelData(localDataPath + "vision.json", localDataPath + "vision.modeldata");
-//        fYunFileService.uploadFile(bucket, localDataPath + "vision.modeldata", viewImagesPath + "vision.modeldata");
-//
-//        //更新版本号
-//        SceneEditInfo editInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
-//        if(Objects.isNull(editInfo)){
-//            editInfo = new SceneEditInfo();
-//            editInfo.setScenePlusId(scenePlus.getId());
-//            sceneEditInfoService.save(editInfo);
-//        }else{
-//            sceneEditInfoService.upgradeVersionAndImgVersionById(editInfo.getId());
-//            //更新scenejson缓存和oss文件版本号
-//            sceneEditInfoService.upgradeSceneJsonVersion(param.getNum(), editInfo.getVersion() + 1, editInfo.getImgVersion() + 1, bucket);
-//        }
-//
-//        return ResultData.ok();
-//    }
+        FileUtil.writeUtf8String(json.toString(), localDataPath + "vision.json");
+        ConvertUtils.convertTxtToVisionModelData(localDataPath + "vision.json", localDataPath + "vision.modeldata");
+        fYunFileService.uploadFile(param.getNum(), localDataPath + "vision.modeldata", viewImagesPath + "vision.modeldata");
+        FileUtil.del(localDataPath + "vision.json");
+        FileUtil.del(localDataPath + "vision.modeldata");
+
+        //更新版本号
+        SceneEditInfo editInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
+        if(Objects.isNull(editInfo)){
+            editInfo = new SceneEditInfo();
+            editInfo.setScenePlusId(scenePlus.getId());
+            sceneEditInfoService.save(editInfo);
+        }else{
+            sceneEditInfoService.upgradeVersionAndImgVersionById(editInfo.getId());
+            //更新scenejson缓存和oss文件版本号
+            sceneEditInfoService.upgradeSceneJsonVersion(param.getNum(), editInfo.getVersion() + 1, editInfo.getImgVersion() + 1);
+        }
+
+        return ResultData.ok();
+    }
 //
 //    @Override
 //    public void updateUserIdByCameraId(Long userId, Long cameraId) {