/*
 * Copyright 2000-2011 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.buildfiles;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.FileAttribute;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.util.io.IOUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: lene
 * Date: 04.04.11
 * Time: 17:40
 */
public class ForcedBuildFileAttribute {
  private static final Logger LOG = Logger.getInstance("#" + ForcedBuildFileAttribute.class.getName());
  private static final Object LOCK = new Object();

  private static final FileAttribute FRAMEWORK_FILE_ATTRIBUTE = new FileAttribute("forcedBuildFileFrameworkAttribute", 1, false);
  private static final Key<String> FRAMEWORK_FILE_MARKER = Key.create("forcedBuildFileFrameworkAttribute");


  private ForcedBuildFileAttribute() {
  }

  public static boolean belongsToFramework(VirtualFile file, @NotNull String frameworkId) {
    return frameworkId.equals(getFrameworkIdOfBuildFile(file));
  }

  @Nullable
  public static String getFrameworkIdOfBuildFile(VirtualFile file) {
    if (file instanceof NewVirtualFile) {
      synchronized (LOCK) {
        final DataInputStream is = FRAMEWORK_FILE_ATTRIBUTE.readAttribute(file);
        if (is != null) {
          try {
            try {
              if (is.available() == 0) {
                return null;
              }
              return IOUtil.readString(is);
            }
            finally {
              is.close();
            }
          }
          catch (IOException e) {
            LOG.error(file.getPath(), e);
          }
        }
        return "";
      }
    }
    return file.getUserData(FRAMEWORK_FILE_MARKER);
  }


  public static void forceFileToFramework(VirtualFile file, String frameworkId, boolean value) {
    //belongs to other framework - do not override!
    String existingFrameworkId = getFrameworkIdOfBuildFile(file);
    if (!StringUtil.isEmpty(existingFrameworkId) && !frameworkId.equals(existingFrameworkId)) {
      return;
    }

    if (value) {//write framework
      forceBuildFile(file, frameworkId);
    }
    else {
      forceBuildFile(file, null);
    }
  }


  private static void forceBuildFile(VirtualFile file, @Nullable String value) {
    if (file instanceof NewVirtualFile) {
      synchronized (LOCK) {
        final DataOutputStream os = FRAMEWORK_FILE_ATTRIBUTE.writeAttribute(file);
        try {
          try {
            IOUtil.writeString(StringUtil.notNullize(value), os);
          }
          finally {
            os.close();
          }
        }
        catch (IOException e) {
          LOG.error(e);
        }
      }
    }
    else {
      file.putUserData(FRAMEWORK_FILE_MARKER, value);
    }
  }
}

@@ -1364,59 +1364,8 @@
 ());
-%0A  private static final Object LOCK = new Object();
 %0A%0A  
@@ -1481,17 +1481,17 @@
 ibute%22, 
-1
+2
 , false)
@@ -1934,38 +1934,8 @@
 ) %7B%0A
-      synchronized (LOCK) %7B%0A  
     
@@ -2011,26 +2011,24 @@
 ile);%0A      
-  
 if (is != nu
@@ -2037,34 +2037,30 @@
 ) %7B%0A        
-  
 try %7B%0A
-  
           tr
@@ -2071,26 +2071,24 @@
             
-  
 if (is.avail
@@ -2112,26 +2112,24 @@
             
-  
 return null;
@@ -2133,38 +2133,34 @@
 ll;%0A            
- 
- 
 %7D%0A
-  
             retu
@@ -2187,38 +2187,34 @@
 (is);%0A          
- 
- 
 %7D%0A
-  
           finall
@@ -2209,34 +2209,32 @@
       finally %7B%0A
-  
             is.c
@@ -2243,38 +2243,34 @@
 se();%0A          
-  %7D%0A  
+%7D%0A
         %7D%0A      
@@ -2267,26 +2267,24 @@
   %7D%0A        
-  
 catch (IOExc
@@ -2287,34 +2287,32 @@
 OException e) %7B%0A
-  
           LOG.er
@@ -2335,38 +2335,34 @@
 (), e);%0A        
-  %7D%0A  
+%7D%0A
       %7D%0A        
@@ -2355,26 +2355,24 @@
     %7D%0A      
- 
- 
 return %22%22;%0A 
@@ -2370,24 +2370,16 @@
 urn %22%22;%0A
-      %7D%0A
     %7D%0A  
@@ -2903,17 +2903,16 @@
  %7D%0A  %7D%0A%0A
-%0A
   privat
@@ -3030,38 +3030,8 @@
 ) %7B%0A
-      synchronized (LOCK) %7B%0A  
     
@@ -3109,34 +3109,30 @@
 ile);%0A      
-  
 try %7B%0A
-  
         try 
@@ -3125,34 +3125,32 @@
 %7B%0A        try %7B%0A
-  
           IOUtil
@@ -3193,26 +3193,24 @@
 alue), os);%0A
-  
         %7D%0A  
@@ -3207,34 +3207,32 @@
       %7D%0A        
-  
 finally %7B%0A      
@@ -3217,34 +3217,32 @@
       finally %7B%0A
-  
           os.clo
@@ -3251,34 +3251,32 @@
 ();%0A        
-  
 %7D%0A      
   %7D%0A        
@@ -3255,38 +3255,34 @@
         %7D%0A      
- 
- 
 %7D%0A
-  
       catch (IOE
@@ -3295,34 +3295,32 @@
 on e) %7B%0A        
-  
 LOG.error(e);%0A  
@@ -3313,34 +3313,24 @@
 G.error(e);%0A
-        %7D%0A
       %7D%0A    

remove unnecessary synchronization and advance attribute format version to fix EOFs